Skip to content

Commit 5f32637

Browse files
committed
Merge branch 'pro' into chore/code-style
2 parents fbf2acb + 6fed7ce commit 5f32637

File tree

7 files changed

+309
-33
lines changed

7 files changed

+309
-33
lines changed

pnpm-lock.yaml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/menu.vue

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div class="container">
33
<Button
4+
v-click-outside="onClickOutside"
45
@click="state.dropdownOpen = !state.dropdownOpen"
56
class="ghost trigger"
67
>
@@ -28,6 +29,24 @@ defineProps({
2829
triggerLabel: String,
2930
});
3031
32+
const onClickOutside = () => {
33+
state.dropdownOpen = false;
34+
};
35+
36+
const vClickOutside = {
37+
mounted: (el, binding, vnode) => {
38+
el.clickOutsideEvent = function (event) {
39+
if (!(el == event.target || el.contains(event.target))) {
40+
binding.value(event);
41+
}
42+
};
43+
document.addEventListener("click", el.clickOutsideEvent);
44+
},
45+
unmounted: (el) => {
46+
document.removeEventListener("click", el.clickOutsideEvent);
47+
},
48+
};
49+
3150
const state = reactive({ dropdownOpen: false });
3251
</script>
3352

src/components/settings-modal.vue

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<template>
2+
<div class="modal">
3+
<div class="modal-container">
4+
<div class="modal-content">
5+
<div class="modal-header">
6+
<h3>Settings</h3>
7+
<Button @click="onClose">
8+
<svg
9+
xmlns="http://www.w3.org/2000/svg"
10+
width="16"
11+
height="16"
12+
viewBox="0 0 24 24"
13+
fill="none"
14+
stroke="currentColor"
15+
stroke-width="2"
16+
stroke-linecap="round"
17+
stroke-linejoin="round"
18+
class="icon icon-tabler icons-tabler-outline icon-tabler-x"
19+
>
20+
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
21+
<path d="M18 6l-12 12" />
22+
<path d="M6 6l12 12" />
23+
</svg>
24+
</Button>
25+
</div>
26+
<div class="modal-body">
27+
<label class="checkbox-container">
28+
<input
29+
v-model="settings.value.rawMode"
30+
type="checkbox"
31+
name="rawMode"
32+
/>
33+
<span class="checkbox">
34+
<span class="checkbox-overlay"></span>
35+
</span>
36+
<span class="checkbox-label">Raw Edit Mode </span>
37+
</label>
38+
</div>
39+
</div>
40+
</div>
41+
</div>
42+
</template>
43+
44+
<script setup>
45+
import { settings } from "../stores/settings";
46+
import Button from "./button.vue";
47+
48+
const props = defineProps(["onClose"]);
49+
</script>
50+
51+
<style>
52+
.modal {
53+
position: fixed;
54+
height: 100vh;
55+
width: 100vw;
56+
top: 0;
57+
left: 0;
58+
}
59+
60+
.modal-container {
61+
height: 100%;
62+
width: 100%;
63+
display: flex;
64+
justify-content: center;
65+
align-items: center;
66+
background: rgba(0, 0, 0, 0.5);
67+
backdrop-filter: blur(4px);
68+
}
69+
70+
.modal-content {
71+
background-color: var(--overlay);
72+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
73+
padding: 20px;
74+
border-radius: 12px;
75+
min-height: 50%;
76+
min-width: 50%;
77+
display: flex;
78+
flex-direction: column;
79+
transition:
80+
transform 0.3s ease,
81+
opacity 0.3s ease;
82+
}
83+
84+
.modal-content .modal-header {
85+
height: auto;
86+
padding: 0 10px;
87+
padding-bottom: 10px;
88+
border-bottom: 1px solid var(--surface);
89+
display: flex;
90+
flex-direction: row;
91+
justify-content: space-between;
92+
align-items: center;
93+
}
94+
95+
.modal-content .modal-header h3 {
96+
margin: 0;
97+
font-weight: 600;
98+
color: var(--text-primary);
99+
}
100+
101+
.modal-content .modal-body {
102+
padding: 15px 10px 0 10px;
103+
font-size: 14px;
104+
color: var(--text-secondary);
105+
}
106+
107+
.toggle-label {
108+
display: flex;
109+
align-items: center;
110+
gap: 8px;
111+
}
112+
113+
input[type="checkbox"] {
114+
width: 18px;
115+
height: 18px;
116+
cursor: pointer;
117+
}
118+
119+
.checkbox-container {
120+
display: inline-flex;
121+
position: relative;
122+
gap: 0.5rem;
123+
}
124+
125+
.checkbox-container input[type="checkbox"] {
126+
display: none;
127+
cursor: pointer;
128+
}
129+
130+
.checkbox-container input[type="checkbox"]:after {
131+
opacity: 1;
132+
}
133+
134+
.checkbox-container .checkbox {
135+
display: inline-flex;
136+
position: absolute;
137+
top: 0px;
138+
left: 0px;
139+
justify-content: center;
140+
align-items: center;
141+
width: 1.25rem;
142+
height: 1.25rem;
143+
border-radius: 0.375rem;
144+
border-width: 2px;
145+
background: overlay;
146+
border-color: var(--text);
147+
border-style: solid;
148+
}
149+
150+
.checkbox-container .checkbox-overlay {
151+
transition-property: all;
152+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
153+
transition-duration: 150ms;
154+
transition-duration: 300ms;
155+
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
156+
display: inline-block;
157+
width: 0.625rem;
158+
height: 0.625rem;
159+
border-radius: 2px;
160+
opacity: 0;
161+
background: var(--text);
162+
}
163+
164+
.checkbox-container .checkbox-label {
165+
margin-left: 2rem;
166+
}
167+
168+
input[type="checkbox"]:checked ~ .checkbox > .checkbox-overlay {
169+
opacity: 1;
170+
}
171+
</style>

src/lib/quill/delta-md.js

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import { marked } from "marked";
12
import { QuillDeltaToHtmlConverter } from "quill-delta-to-html";
3+
import Quill from "quill";
24
import TurndownService from "turndown";
35
const turndownService = new TurndownService({
46
codeBlockStyle: "fenced",
@@ -19,14 +21,26 @@ export const deltaToMarkdown = (delta) => {
1921
const html = new QuillDeltaToHtmlConverter(delta, {});
2022
html.beforeRender((groupType, data) => {
2123
if (groupType !== "block") return;
22-
if (!(data.op && "code-block" in data.op.attributes)) return;
23-
return `<pre data-language="${
24-
data.op.attributes["code-block"]
25-
}"><code>${data.ops
26-
.map((d) => {
27-
return d.insert.value;
28-
})
29-
.join("")}</code></pre>`;
24+
if (!(data.op && data.op.attributes && data.op.attributes["code-block"]))
25+
return;
26+
const codeContent = data.ops
27+
.map((d) =>
28+
typeof d.insert === "string"
29+
? d.insert
30+
: d.insert && d.insert.value
31+
? d.insert.value
32+
: "",
33+
)
34+
.join("");
35+
return `<pre data-language="${data.op.attributes["code-block"]}"><code>${codeContent}</code></pre>`;
3036
});
3137
return htmlToMarkdown(html.convert());
3238
};
39+
40+
export const markdownToDelta = (markdown) => {
41+
const html = marked(markdown);
42+
const container = document.createElement("div");
43+
container.innerHTML = html;
44+
const quillInstance = new Quill(container);
45+
return quillInstance.getContents().ops;
46+
};

src/lib/settings.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const KEY = "mark:settings";
2+
3+
const settings = {};
4+
5+
export const loadSettings = () => {
6+
const _settings = localStorage.getItem(KEY) || "{}";
7+
try {
8+
Object.assign(settings, JSON.parse(_settings));
9+
} catch (err) {
10+
Object.assign(settings, {});
11+
}
12+
return settings;
13+
};
14+
15+
export const saveSettings = () => {
16+
localStorage.setItem(KEY, JSON.stringify(settings));
17+
};
18+
19+
export const updateSettings = (patch) => {
20+
Object.assign(settings, patch);
21+
saveSettings();
22+
};

0 commit comments

Comments
 (0)