Skip to content

Commit 0868863

Browse files
committed
Update language options and add database migration scripts
1 parent b622846 commit 0868863

File tree

17 files changed

+1452
-172
lines changed

17 files changed

+1452
-172
lines changed

assets/languages.js

-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@ export default [
2020
"elixir",
2121
"flow9",
2222
"freemarker2",
23-
"freemarker2.tag-angle.interpolation-dollar",
24-
"freemarker2.tag-bracket.interpolation-dollar",
25-
"freemarker2.tag-angle.interpolation-bracket",
26-
"freemarker2.tag-bracket.interpolation-bracket",
27-
"freemarker2.tag-auto.interpolation-dollar",
28-
"freemarker2.tag-auto.interpolation-bracket",
2923
"fsharp",
3024
"go",
3125
"graphql",

components/App/Footer/index.vue

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<template>
2+
<footer
3+
class="border-t bg-gray-900 border-white/10 flex items-center justify-between"
4+
>
5+
<div
6+
class="flex items-center divide-x divide-white/10 text-xs [&>div]:p-2 border-r border-white/10"
7+
>
8+
<div>
9+
<span class="font-semibold">{{ wordCount }}</span>
10+
<span class="text-gray-300"> words</span>
11+
</div>
12+
<div>
13+
<span class="font-semibold">{{ letterCount }}</span>
14+
<span class="text-gray-300"> letters</span>
15+
</div>
16+
<div>
17+
<span class="font-semibold">{{ lineCount }}</span>
18+
<span class="text-gray-300"> lines</span>
19+
</div>
20+
</div>
21+
<div
22+
class="flex items-center divide-x divide-white/10 text-xs border-l border-white/10"
23+
>
24+
<UTooltip
25+
:text="`Toggle minimap (${
26+
MONACO_EDITOR_OPTIONS.minimap.enabled ? 'on' : 'off'
27+
})`"
28+
:shortcuts="['CTRL', 'M']"
29+
:popper="{ placement: 'top' }"
30+
>
31+
<button class="p-2 hover:bg-gray-950" @click="toggleMinimap">
32+
<Icon name="i-heroicons-map" class="h-4 w-4" />
33+
</button>
34+
</UTooltip>
35+
<UTooltip
36+
text="Format code"
37+
:shortcuts="['CTRL', 'F']"
38+
:popper="{ placement: 'top' }"
39+
>
40+
<button class="p-2 hover:bg-gray-950" @click="formatCode">
41+
<Icon name="i-lucide-sparkles" class="h-4 w-4" />
42+
</button>
43+
</UTooltip>
44+
<USelectMenu
45+
v-model="selectedLanguage"
46+
:options="languages"
47+
class="w-48"
48+
searchable
49+
id="language-select"
50+
searchable-placeholder="Search a language..."
51+
:ui="{ rounded: '' }"
52+
/>
53+
</div>
54+
</footer>
55+
</template>
56+
57+
<script setup></script>
58+
59+
<style></style>

components/App/Navbar/index.vue

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<template>
2+
<header
3+
class="border-b bg-gray-900 border-white/10 flex items-center justify-between gap-3"
4+
>
5+
<h1 class="font-bold tracking-wide flex items-center gap-2 px-4">
6+
<Icon class="h-5 w-5" name="i-lucide-chevron-right-square" /><span
7+
>CODESHARE</span
8+
>
9+
</h1>
10+
<UInput v-model="snippet.title" placeholder="file.txt" size="2xs" />
11+
<div
12+
class="border-l divide-x divide-white/10 border-white/10 flex items-center"
13+
>
14+
<UTooltip text="Download file">
15+
<button class="border-white/10 h-9 px-3 text-sm hover:bg-gray-950">
16+
<Icon name="i-lucide-download" class="h-4 w-4" />
17+
</button>
18+
</UTooltip>
19+
<UTooltip text="Copy code">
20+
<button class="border-white/10 h-9 px-3 text-sm hover:bg-gray-950">
21+
<Icon name="i-lucide-copy" class="h-4 w-4" />
22+
</button>
23+
</UTooltip>
24+
<UTooltip text="Fork">
25+
<button class="border-white/10 h-9 px-3 text-sm hover:bg-gray-950">
26+
<Icon name="i-lucide-git-fork" class="h-4 w-4" />
27+
</button>
28+
</UTooltip>
29+
<UTooltip text="Publish">
30+
<button
31+
@click="$emit('publish')"
32+
class="border-white/10 h-9 px-3 text-sm hover:bg-gray-950"
33+
>
34+
<Icon name="i-lucide-external-link" class="h-4 w-4" />
35+
</button>
36+
</UTooltip>
37+
</div>
38+
</header>
39+
</template>
40+
41+
<script setup>
42+
const { snippet } = useEditor();
43+
</script>
44+
45+
<style></style>

components/App/Sidebar/index.vue

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<template>
2+
<aside
3+
class="aside sticky top-0 border-r border-white/10 w-12 flex flex-col items-center py-0.5 z-[50]"
4+
>
5+
<UTooltip
6+
text="New code bin"
7+
:shortcuts="['CTRL', 'N']"
8+
:popper="{ placement: 'right' }"
9+
>
10+
<UButton
11+
icon="i-lucide-file-code-2"
12+
square
13+
variant="ghost"
14+
color="gray"
15+
size="lg"
16+
class="flex items-center justify-center"
17+
/>
18+
</UTooltip>
19+
<UTooltip
20+
text="New diff editor"
21+
:shortcuts="['CTRL', 'D']"
22+
:popper="{ placement: 'right' }"
23+
>
24+
<UButton
25+
icon="i-lucide-file-diff"
26+
square
27+
variant="ghost"
28+
color="gray"
29+
size="lg"
30+
class="flex items-center justify-center"
31+
/>
32+
</UTooltip>
33+
</aside>
34+
</template>
35+
<script setup></script>
36+
<style scoped></style>

composables/editor.js

+89-83
Original file line numberDiff line numberDiff line change
@@ -20,87 +20,93 @@ export const useEditor = () => {
2020
enabled: true,
2121
},
2222
});
23-
const selectedLanguage = ref("javascript");
24-
const code = ref(`/**
25-
* converts an svg string to base64 png using the domUrl
26-
* @param {string} svgText the svgtext
27-
* @param {number} [margin=0] the width of the border - the image size will be height+margin by width+margin
28-
* @param {string} [fill] optionally backgrund canvas fill
29-
* @return {Promise} a promise to the bas64 png image
30-
*/
31-
var svgToPng = function (svgText, margin, fill) {
32-
// convert an svg text to png using the browser
33-
return new Promise(function (resolve, reject) {
34-
try {
35-
// can use the domUrl function from the browser
36-
var domUrl = window.URL || window.webkitURL || window;
37-
if (!domUrl) {
38-
throw new Error("(browser doesnt support this)")
39-
}
40-
41-
// figure out the height and width from svg text
42-
var match = svgText.match(/height="(d+)/m);
43-
var height = match && match[1] ? parseInt(match[1], 10) : 200;
44-
var match = svgText.match(/width="(d+)/m);
45-
var width = match && match[1] ? parseInt(match[1], 10) : 200;
46-
margin = margin || 0;
47-
48-
// it needs a namespace
49-
if (!svgText.match(/xmlns="/mi)) {
50-
svgText = svgText.replace('<svg ', '<svg xmlns="http://www.w3.org/2000/svg" ');
51-
}
52-
53-
// create a canvas element to pass through
54-
var canvas = document.createElement("canvas");
55-
canvas.width = height + margin * 2;
56-
canvas.height = width + margin * 2;
57-
var ctx = canvas.getContext("2d");
58-
59-
60-
// make a blob from the svg
61-
var svg = new Blob([svgText], {
62-
type: "image/svg+xml;charset=utf-8"
63-
});
64-
65-
// create a dom object for that image
66-
var url = domUrl.createObjectURL(svg);
67-
68-
// create a new image to hold it the converted type
69-
var img = new Image;
70-
71-
// when the image is loaded we can get it as base64 url
72-
img.onload = function () {
73-
// draw it to the canvas
74-
ctx.drawImage(this, margin, margin);
75-
76-
// if it needs some styling, we need a new canvas
77-
if (fill) {
78-
var styled = document.createElement("canvas");
79-
styled.width = canvas.width;
80-
styled.height = canvas.height;
81-
var styledCtx = styled.getContext("2d");
82-
styledCtx.save();
83-
styledCtx.fillStyle = fill;
84-
styledCtx.fillRect(0, 0, canvas.width, canvas.height);
85-
styledCtx.strokeRect(0, 0, canvas.width, canvas.height);
86-
styledCtx.restore();
87-
styledCtx.drawImage(canvas, 0, 0);
88-
canvas = styled;
23+
const snippet = useState("snippet", () => {
24+
return {
25+
title: "index.txt",
26+
body: `/**
27+
* converts an svg string to base64 png using the domUrl
28+
* @param {string} svgText the svgtext
29+
* @param {number} [margin=0] the width of the border - the image size will be height+margin by width+margin
30+
* @param {string} [fill] optionally backgrund canvas fill
31+
* @return {Promise} a promise to the bas64 png image
32+
*/
33+
var svgToPng = function (svgText, margin, fill) {
34+
// convert an svg text to png using the browser
35+
return new Promise(function (resolve, reject) {
36+
try {
37+
// can use the domUrl function from the browser
38+
var domUrl = window.URL || window.webkitURL || window;
39+
if (!domUrl) {
40+
throw new Error("(browser doesnt support this)")
41+
}
42+
43+
// figure out the height and width from svg text
44+
var match = svgText.match(/height="(d+)/m);
45+
var height = match && match[1] ? parseInt(match[1], 10) : 200;
46+
var match = svgText.match(/width="(d+)/m);
47+
var width = match && match[1] ? parseInt(match[1], 10) : 200;
48+
margin = margin || 0;
49+
50+
// it needs a namespace
51+
if (!svgText.match(/xmlns="/mi)) {
52+
svgText = svgText.replace('<svg ', '<svg xmlns="http://www.w3.org/2000/svg" ');
53+
}
54+
55+
// create a canvas element to pass through
56+
var canvas = document.createElement("canvas");
57+
canvas.width = height + margin * 2;
58+
canvas.height = width + margin * 2;
59+
var ctx = canvas.getContext("2d");
60+
61+
62+
// make a blob from the svg
63+
var svg = new Blob([svgText], {
64+
type: "image/svg+xml;charset=utf-8"
65+
});
66+
67+
// create a dom object for that image
68+
var url = domUrl.createObjectURL(svg);
69+
70+
// create a new image to hold it the converted type
71+
var img = new Image;
72+
73+
// when the image is loaded we can get it as base64 url
74+
img.onload = function () {
75+
// draw it to the canvas
76+
ctx.drawImage(this, margin, margin);
77+
78+
// if it needs some styling, we need a new canvas
79+
if (fill) {
80+
var styled = document.createElement("canvas");
81+
styled.width = canvas.width;
82+
styled.height = canvas.height;
83+
var styledCtx = styled.getContext("2d");
84+
styledCtx.save();
85+
styledCtx.fillStyle = fill;
86+
styledCtx.fillRect(0, 0, canvas.width, canvas.height);
87+
styledCtx.strokeRect(0, 0, canvas.width, canvas.height);
88+
styledCtx.restore();
89+
styledCtx.drawImage(canvas, 0, 0);
90+
canvas = styled;
91+
}
92+
// we don't need the original any more
93+
domUrl.revokeObjectURL(url);
94+
// now we can resolve the promise, passing the base64 url
95+
resolve(canvas.toDataURL());
96+
};
97+
98+
// load the image
99+
img.src = url;
100+
101+
} catch (err) {
102+
reject('failed to convert svg to png ' + err);
89103
}
90-
// we don't need the original any more
91-
domUrl.revokeObjectURL(url);
92-
// now we can resolve the promise, passing the base64 url
93-
resolve(canvas.toDataURL());
94-
};
95-
96-
// load the image
97-
img.src = url;
98-
99-
} catch (err) {
100-
reject('failed to convert svg to png ' + err);
101-
}
104+
});
105+
};`,
106+
language: "javascript",
107+
};
102108
});
103-
};`);
109+
const selectedLanguage = ref("javascript");
104110
const lineCount = ref(0);
105111
const editorRef = shallowRef();
106112
const handleMount = (editor, monaco) => {
@@ -111,13 +117,13 @@ var svgToPng = function (svgText, margin, fill) {
111117
};
112118

113119
const wordCount = computed(() => {
114-
const text = code.value;
120+
const text = snippet.value.body;
115121
const words = text.match(/\w+/g);
116122
return words ? words.length : 0;
117123
});
118124

119125
const letterCount = computed(() => {
120-
const text = code.value;
126+
const text = snippet.value.body;
121127
return text.length;
122128
});
123129

@@ -134,16 +140,16 @@ var svgToPng = function (svgText, margin, fill) {
134140
MONACO_EDITOR_OPTIONS.value.minimap.enabled =
135141
!MONACO_EDITOR_OPTIONS.value.minimap.enabled;
136142
}
137-
143+
138144
return {
139145
MONACO_EDITOR_OPTIONS,
140146
selectedLanguage,
141147
languages,
142-
code,
143148
lineCount,
144149
wordCount,
145150
letterCount,
146151
editorRef,
152+
snippet,
147153
toggleMinimap,
148154
handleMount,
149155
onChange,

drizzle.config.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import "dotenv/config";
2+
const { TURSO_DB_URL, TURSO_DB_TOKEN } = process.env;
3+
4+
const turso = {
5+
driver: "turso",
6+
dbCredentials: {
7+
url: TURSO_DB_URL,
8+
authToken: TURSO_DB_TOKEN,
9+
},
10+
};
11+
12+
export default {
13+
schema: "./server/database/schema.ts",
14+
out: "./server/database/migrations",
15+
...turso,
16+
};

0 commit comments

Comments
 (0)