@sierra-95/svelte-scaffold 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/Hooks/layout_menu.d.ts +1 -0
- package/dist/Hooks/layout_menu.js +24 -0
- package/dist/Hooks/preview.d.ts +3 -0
- package/dist/Hooks/preview.js +24 -0
- package/dist/components/Core/Alerts/Backdrop/backdrop.svelte +27 -0
- package/dist/components/Core/Alerts/Backdrop/backdrop.svelte.d.ts +15 -0
- package/dist/components/Core/Alerts/Modal/modal.svelte +40 -0
- package/dist/components/Core/Alerts/Modal/modal.svelte.d.ts +26 -0
- package/dist/components/Core/Alerts/Toast/toast.css +39 -0
- package/dist/components/Core/Alerts/Toast/toast.svelte +32 -0
- package/dist/components/Core/Alerts/Toast/toast.svelte.d.ts +26 -0
- package/dist/components/Core/Alerts/Wrapper/wrapper.svelte +19 -0
- package/dist/components/Core/Alerts/Wrapper/wrapper.svelte.d.ts +17 -0
- package/dist/components/Core/Alerts/site-under-maintenance/site-under-maintenance.svelte +34 -0
- package/dist/components/Core/Alerts/site-under-maintenance/site-under-maintenance.svelte.d.ts +11 -0
- package/dist/components/Core/Form/Hr/hr.svelte +11 -0
- package/dist/components/Core/Form/Hr/hr.svelte.d.ts +21 -0
- package/dist/components/Core/Form/Input/FileInput/fileInput.svelte +130 -0
- package/dist/components/Core/Form/Input/FileInput/fileInput.svelte.d.ts +6 -0
- package/dist/components/Core/Form/Input/FileInput/preview.svelte +38 -0
- package/dist/components/Core/Form/Input/FileInput/preview.svelte.d.ts +18 -0
- package/dist/components/Core/Form/Input/input/input.svelte +17 -0
- package/dist/components/Core/Form/Input/input/input.svelte.d.ts +24 -0
- package/dist/components/Core/Form/Input/password/password.svelte +27 -0
- package/dist/components/Core/Form/Input/password/password.svelte.d.ts +23 -0
- package/dist/components/Core/Menus/DropdownContainer/dropdown.svelte +94 -0
- package/dist/components/Core/Menus/DropdownContainer/dropdown.svelte.d.ts +9 -0
- package/dist/components/Core/Menus/MenuItem/menuItem.svelte +44 -0
- package/dist/components/Core/Menus/MenuItem/menuItem.svelte.d.ts +10 -0
- package/dist/components/Core/Menus/UserMenu/profile.svelte +35 -0
- package/dist/components/Core/Menus/UserMenu/profile.svelte.d.ts +11 -0
- package/dist/components/Core/others/Button/Flip/button.css +51 -0
- package/dist/components/Core/others/Button/Flip/button.svelte +69 -0
- package/dist/components/Core/others/Button/Flip/button.svelte.d.ts +21 -0
- package/dist/components/Core/others/Button/Marquee/button.css +37 -0
- package/dist/components/Core/others/Button/Marquee/button.svelte +45 -0
- package/dist/components/Core/others/Button/Marquee/button.svelte.d.ts +9 -0
- package/dist/components/Core/others/Button/Swipe/button.css +31 -0
- package/dist/components/Core/others/Button/Swipe/button.svelte +45 -0
- package/dist/components/Core/others/Button/Swipe/button.svelte.d.ts +17 -0
- package/dist/components/Core/others/Button/default/button.css +52 -0
- package/dist/components/Core/others/Button/default/button.svelte +112 -0
- package/dist/components/Core/others/Button/default/button.svelte.d.ts +16 -0
- package/dist/components/Core/others/Button/select/select.svelte +29 -0
- package/dist/components/Core/others/Button/select/select.svelte.d.ts +3 -0
- package/dist/components/Core/others/Button/theme/theme.css +122 -0
- package/dist/components/Core/others/Button/theme/theme.svelte +68 -0
- package/dist/components/Core/others/Button/theme/theme.svelte.d.ts +19 -0
- package/dist/components/Core/others/Button/times/times.svelte +25 -0
- package/dist/components/Core/others/Button/times/times.svelte.d.ts +6 -0
- package/dist/components/Core/others/Clock/Date/date.svelte +25 -0
- package/dist/components/Core/others/Clock/Date/date.svelte.d.ts +20 -0
- package/dist/components/Core/others/Clock/Time/time.svelte +35 -0
- package/dist/components/Core/others/Clock/Time/time.svelte.d.ts +20 -0
- package/dist/components/Core/others/Previews/Audio/audio.svelte +62 -0
- package/dist/components/Core/others/Previews/Audio/audio.svelte.d.ts +22 -0
- package/dist/components/Core/others/Previews/Document/documents.svelte +25 -0
- package/dist/components/Core/others/Previews/Document/documents.svelte.d.ts +22 -0
- package/dist/components/Core/others/Previews/Image/image.svelte +27 -0
- package/dist/components/Core/others/Previews/Image/image.svelte.d.ts +22 -0
- package/dist/components/Core/others/Previews/Video/video.svelte +29 -0
- package/dist/components/Core/others/Previews/Video/video.svelte.d.ts +24 -0
- package/dist/components/Core/others/Progress/CircularProgress/CircularProgress.svelte +55 -0
- package/dist/components/Core/others/Progress/CircularProgress/CircularProgress.svelte.d.ts +15 -0
- package/dist/components/Core/others/Progress/LinearProgress/LinearProgress.css +61 -0
- package/dist/components/Core/others/Progress/LinearProgress/LinearProgress.svelte +79 -0
- package/dist/components/Core/others/Progress/LinearProgress/LinearProgress.svelte.d.ts +26 -0
- package/dist/components/Modules/Editor/Hooks/extractContent.d.ts +7 -0
- package/dist/components/Modules/Editor/Hooks/extractContent.js +15 -0
- package/dist/components/Modules/Editor/Hooks/extractImage.d.ts +7 -0
- package/dist/components/Modules/Editor/Hooks/extractImage.js +30 -0
- package/dist/components/Modules/Editor/Hooks/insertImage.d.ts +5 -0
- package/dist/components/Modules/Editor/Hooks/insertImage.js +27 -0
- package/dist/components/Modules/Editor/Hooks/insertYoutube.d.ts +6 -0
- package/dist/components/Modules/Editor/Hooks/insertYoutube.js +35 -0
- package/dist/components/Modules/Editor/Marks/Links/links.svelte +79 -0
- package/dist/components/Modules/Editor/Marks/Links/links.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Marks/TextFormatting/textFormatting.svelte +32 -0
- package/dist/components/Modules/Editor/Marks/TextFormatting/textFormatting.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/Headings/heading.svelte +58 -0
- package/dist/components/Modules/Editor/Nodes/Headings/heading.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/History/history.svelte +21 -0
- package/dist/components/Modules/Editor/Nodes/History/history.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/Images/images.svelte +85 -0
- package/dist/components/Modules/Editor/Nodes/Images/images.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/Lists/lists.svelte +30 -0
- package/dist/components/Modules/Editor/Nodes/Lists/lists.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/TextAlign/textAlign.svelte +55 -0
- package/dist/components/Modules/Editor/Nodes/TextAlign/textAlign.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/Nodes/TextColor/styles.css +18 -0
- package/dist/components/Modules/Editor/Nodes/TextColor/textColor.svelte +88 -0
- package/dist/components/Modules/Editor/Nodes/TextColor/textColor.svelte.d.ts +22 -0
- package/dist/components/Modules/Editor/Nodes/Youtube/youtube.svelte +32 -0
- package/dist/components/Modules/Editor/Nodes/Youtube/youtube.svelte.d.ts +21 -0
- package/dist/components/Modules/Editor/colors.d.ts +2 -0
- package/dist/components/Modules/Editor/colors.js +21 -0
- package/dist/components/Modules/Editor/controls.svelte +72 -0
- package/dist/components/Modules/Editor/controls.svelte.d.ts +24 -0
- package/dist/components/Modules/Editor/extensions.d.ts +1 -0
- package/dist/components/Modules/Editor/extensions.js +59 -0
- package/dist/components/Modules/Editor/main.svelte +42 -0
- package/dist/components/Modules/Editor/main.svelte.d.ts +25 -0
- package/dist/components/Modules/Editor/save.svelte +28 -0
- package/dist/components/Modules/Editor/save.svelte.d.ts +23 -0
- package/dist/components/Modules/Editor/styles/controls.css +70 -0
- package/dist/components/Modules/Editor/styles/main.css +43 -0
- package/dist/components/Modules/Editor/tools.d.ts +14 -0
- package/dist/components/Modules/Editor/tools.js +23 -0
- package/dist/components/Modules/FilePicker/cloudStore.svelte +96 -0
- package/dist/components/Modules/FilePicker/cloudStore.svelte.d.ts +20 -0
- package/dist/components/Modules/FilePicker/controls.svelte +122 -0
- package/dist/components/Modules/FilePicker/controls.svelte.d.ts +20 -0
- package/dist/components/Modules/FilePicker/filePicker.svelte +61 -0
- package/dist/components/Modules/FilePicker/filePicker.svelte.d.ts +18 -0
- package/dist/components/Modules/FilePicker/previews.svelte +19 -0
- package/dist/components/Modules/FilePicker/previews.svelte.d.ts +20 -0
- package/dist/components/Modules/Layout/Header/header.css +38 -0
- package/dist/components/Modules/Layout/Header/header.svelte +29 -0
- package/dist/components/Modules/Layout/Header/header.svelte.d.ts +21 -0
- package/dist/components/Modules/Layout/Menu/menu.css +45 -0
- package/dist/components/Modules/Layout/Menu/menu.svelte +129 -0
- package/dist/components/Modules/Layout/Menu/menu.svelte.d.ts +24 -0
- package/dist/components/Modules/Layout/background.svelte +28 -0
- package/dist/components/Modules/Layout/background.svelte.d.ts +26 -0
- package/dist/components/Modules/Layout/main.css +21 -0
- package/dist/components/Modules/Layout/main.svelte +119 -0
- package/dist/components/Modules/Layout/main.svelte.d.ts +27 -0
- package/dist/global.css +226 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +53 -0
- package/dist/stores/core/general.d.ts +3 -0
- package/dist/stores/core/general.js +5 -0
- package/dist/stores/core/ismobile.d.ts +1 -0
- package/dist/stores/core/ismobile.js +14 -0
- package/dist/stores/core/modal.d.ts +14 -0
- package/dist/stores/core/modal.js +35 -0
- package/dist/stores/core/user.d.ts +9 -0
- package/dist/stores/core/user.js +14 -0
- package/dist/stores/modules/editor.d.ts +9 -0
- package/dist/stores/modules/editor.js +14 -0
- package/dist/stores/modules/fileInput.d.ts +22 -0
- package/dist/stores/modules/fileInput.js +25 -0
- package/dist/stores/modules/toast.d.ts +8 -0
- package/dist/stores/modules/toast.js +21 -0
- package/package.json +75 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import StarterKit from '@tiptap/starter-kit';
|
|
2
|
+
import TextAlign from '@tiptap/extension-text-align';
|
|
3
|
+
import Image from '@tiptap/extension-image';
|
|
4
|
+
import Link from '@tiptap/extension-link';
|
|
5
|
+
import Highlight from '@tiptap/extension-highlight';
|
|
6
|
+
import Color from '@tiptap/extension-color';
|
|
7
|
+
import { TextStyle } from '@tiptap/extension-text-style';
|
|
8
|
+
import Heading from '@tiptap/extension-heading';
|
|
9
|
+
import Youtube from '@tiptap/extension-youtube';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
export const extensions = [
|
|
13
|
+
StarterKit.configure({
|
|
14
|
+
heading: false,
|
|
15
|
+
link: false,
|
|
16
|
+
}),
|
|
17
|
+
TextStyle,
|
|
18
|
+
Color,
|
|
19
|
+
TextAlign.configure({ types: ['heading', 'paragraph'] }),
|
|
20
|
+
Link.extend({
|
|
21
|
+
onCreate() {
|
|
22
|
+
this.editor.on('transaction', ({ transaction }) => {
|
|
23
|
+
// Only proceed if it's a text insertion
|
|
24
|
+
if (!transaction.docChanged) return;
|
|
25
|
+
|
|
26
|
+
const { selection } = transaction;
|
|
27
|
+
const { $from } = selection;
|
|
28
|
+
|
|
29
|
+
// Check if we just inserted a space at the end of a link
|
|
30
|
+
const linkMark = $from.marks().find(mark => mark.type.name === 'link');
|
|
31
|
+
if (!linkMark) return;
|
|
32
|
+
|
|
33
|
+
const nodeBefore = $from.nodeBefore;
|
|
34
|
+
if (nodeBefore?.isText && nodeBefore.text?.endsWith(' ')) {
|
|
35
|
+
// Use setTimeout to avoid infinite loops
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
this.editor.commands.command(({ tr }) => {
|
|
38
|
+
tr.removeMark($from.pos - 1, $from.pos, this.type);
|
|
39
|
+
return true;
|
|
40
|
+
});
|
|
41
|
+
}, 0);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}).configure({openOnClick: false,}),
|
|
46
|
+
Image,
|
|
47
|
+
Highlight.configure({
|
|
48
|
+
multicolor: true,
|
|
49
|
+
}),
|
|
50
|
+
Heading.configure({
|
|
51
|
+
levels: [1, 2, 3, 4, 5, 6],
|
|
52
|
+
}),
|
|
53
|
+
Youtube.configure({
|
|
54
|
+
width: 560,
|
|
55
|
+
height: 315,
|
|
56
|
+
controls: true,
|
|
57
|
+
nocookie: true,
|
|
58
|
+
}),
|
|
59
|
+
];
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount, onDestroy } from 'svelte';
|
|
3
|
+
import { Editor } from '@tiptap/core';
|
|
4
|
+
import {extensions} from './extensions.js';
|
|
5
|
+
import Controls from './controls.svelte';
|
|
6
|
+
import {resetEditorStore} from '../../../index.js';
|
|
7
|
+
import './styles/main.css';
|
|
8
|
+
|
|
9
|
+
export let content: any = {};
|
|
10
|
+
export let readOnly: boolean = false;
|
|
11
|
+
export const exportText: string = 'Save';
|
|
12
|
+
|
|
13
|
+
let editor: Editor;
|
|
14
|
+
let element: HTMLElement;
|
|
15
|
+
|
|
16
|
+
onMount(() => {
|
|
17
|
+
editor = new Editor({
|
|
18
|
+
element,
|
|
19
|
+
extensions,
|
|
20
|
+
autofocus: 'end',
|
|
21
|
+
editable: !readOnly,
|
|
22
|
+
onTransaction: () => {
|
|
23
|
+
editor = editor;
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
if (editor && content?.json_content) {
|
|
27
|
+
editor.commands.setContent(content.json_content);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
onDestroy(() => {
|
|
32
|
+
editor?.destroy();
|
|
33
|
+
resetEditorStore();
|
|
34
|
+
});
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<main id="editor">
|
|
38
|
+
{#if editor && !readOnly}
|
|
39
|
+
<Controls bind:content {exportText} {editor} />
|
|
40
|
+
{/if}
|
|
41
|
+
<div bind:this={element}></div>
|
|
42
|
+
</main>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import './styles/main.css';
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: Props & {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Main: $$__sveltets_2_IsomorphicComponent<{
|
|
16
|
+
content?: any;
|
|
17
|
+
readOnly?: boolean;
|
|
18
|
+
exportText?: string;
|
|
19
|
+
}, {
|
|
20
|
+
[evt: string]: CustomEvent<any>;
|
|
21
|
+
}, {}, {
|
|
22
|
+
exportText: string;
|
|
23
|
+
}, string>;
|
|
24
|
+
type Main = InstanceType<typeof Main>;
|
|
25
|
+
export default Main;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { setToastMessage,isLoading, Button} from '../../../index.js';
|
|
3
|
+
import { exractContent } from './tools.js';
|
|
4
|
+
|
|
5
|
+
import type { Editor } from "@tiptap/core";
|
|
6
|
+
export let editor: Editor;
|
|
7
|
+
export let exportText: string;
|
|
8
|
+
export let content: any = {};
|
|
9
|
+
|
|
10
|
+
$: disabled = $isLoading || editor?.isEmpty;
|
|
11
|
+
|
|
12
|
+
async function onSave() {
|
|
13
|
+
try {
|
|
14
|
+
isLoading.set(true);
|
|
15
|
+
content = await exractContent(editor);
|
|
16
|
+
}catch (error) {
|
|
17
|
+
setToastMessage('error', 'An error occurred while saving.');
|
|
18
|
+
} finally {
|
|
19
|
+
isLoading.set(false);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<Button
|
|
26
|
+
onclick={onSave}
|
|
27
|
+
disabled={disabled}
|
|
28
|
+
>{exportText}</Button>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Editor } from "@tiptap/core";
|
|
2
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
3
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
|
+
$$bindings?: Bindings;
|
|
5
|
+
} & Exports;
|
|
6
|
+
(internal: unknown, props: Props & {
|
|
7
|
+
$$events?: Events;
|
|
8
|
+
$$slots?: Slots;
|
|
9
|
+
}): Exports & {
|
|
10
|
+
$set?: any;
|
|
11
|
+
$on?: any;
|
|
12
|
+
};
|
|
13
|
+
z_$$bindings?: Bindings;
|
|
14
|
+
}
|
|
15
|
+
declare const Save: $$__sveltets_2_IsomorphicComponent<{
|
|
16
|
+
editor: Editor;
|
|
17
|
+
exportText: string;
|
|
18
|
+
content?: any;
|
|
19
|
+
}, {
|
|
20
|
+
[evt: string]: CustomEvent<any>;
|
|
21
|
+
}, {}, {}, string>;
|
|
22
|
+
type Save = InstanceType<typeof Save>;
|
|
23
|
+
export default Save;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#editor #controls{
|
|
2
|
+
margin: 0px 10px;
|
|
3
|
+
padding-top: 5px;
|
|
4
|
+
}
|
|
5
|
+
#editor #controls .controls-menu i {
|
|
6
|
+
display: none;
|
|
7
|
+
}
|
|
8
|
+
#editor #controls .controls-menu #sierra-menu-item i{
|
|
9
|
+
display: inline-block;
|
|
10
|
+
}
|
|
11
|
+
@media (max-width: 400px) {
|
|
12
|
+
#editor #controls .controls-menu span {
|
|
13
|
+
display: none;
|
|
14
|
+
}
|
|
15
|
+
#editor #controls .controls-menu i {
|
|
16
|
+
display: inline-block;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
#editor #controls .controls {
|
|
20
|
+
margin-top: 5px;
|
|
21
|
+
position: relative;
|
|
22
|
+
background-color: var(--background-tertiary);
|
|
23
|
+
border-radius: 15px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#editor #controls .controls-buttons {
|
|
27
|
+
display: flex;
|
|
28
|
+
flex-wrap: wrap;
|
|
29
|
+
align-items: center;
|
|
30
|
+
padding: 2px 10px;
|
|
31
|
+
gap: 10px;
|
|
32
|
+
position: absolute;
|
|
33
|
+
top: 0;
|
|
34
|
+
left: 0;
|
|
35
|
+
width: 100%;
|
|
36
|
+
opacity: 0;
|
|
37
|
+
pointer-events: none;
|
|
38
|
+
transition: opacity 0.2s ease;
|
|
39
|
+
}
|
|
40
|
+
#editor #controls .controls-buttons.active {
|
|
41
|
+
position: relative;
|
|
42
|
+
opacity: 1;
|
|
43
|
+
pointer-events: all;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
#editor #controls button{
|
|
47
|
+
align-self:center;
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
padding: 2px;
|
|
50
|
+
border-radius: 3px;
|
|
51
|
+
transition: background-color 0.3s ease, color 0.1s ease;
|
|
52
|
+
}
|
|
53
|
+
#editor #controls button.active{
|
|
54
|
+
color: var(--background);
|
|
55
|
+
background-color: var(--text);
|
|
56
|
+
}
|
|
57
|
+
#editor #controls button:disabled{
|
|
58
|
+
opacity: 0.5;
|
|
59
|
+
cursor: not-allowed;
|
|
60
|
+
}
|
|
61
|
+
#editor #controls button:hover:not(.active):not(.base-btn) {
|
|
62
|
+
color: var(--primary-bg);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
#editor #controls i.fa-chevron-down {
|
|
66
|
+
transition: transform 0.2s;
|
|
67
|
+
}
|
|
68
|
+
#editor #controls i.fa-chevron-down.active {
|
|
69
|
+
transform: rotate(180deg);
|
|
70
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#editor{
|
|
2
|
+
height: 100%;
|
|
3
|
+
background-color: var(--background-secondary);
|
|
4
|
+
box-shadow: var(--box-shadow);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/*TipTap*/
|
|
8
|
+
.tiptap{
|
|
9
|
+
padding: 20px;
|
|
10
|
+
outline: none;
|
|
11
|
+
height: 100%;
|
|
12
|
+
overflow-y: auto;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.tiptap h1 { font-size: 2rem; font-weight: bold; }
|
|
16
|
+
.tiptap h2 { font-size: 1.5rem; font-weight: bold; }
|
|
17
|
+
.tiptap h3 { font-size: 1.17rem; font-weight: bold; }
|
|
18
|
+
.tiptap h4 { font-size: 1rem; font-weight: 400; }
|
|
19
|
+
.tiptap h5 { font-size: 0.83rem; font-weight: 400; }
|
|
20
|
+
.tiptap h6 { font-size: 0.67rem; font-weight: 400; }
|
|
21
|
+
|
|
22
|
+
.tiptap a{
|
|
23
|
+
cursor: pointer;
|
|
24
|
+
color: var(--primary-bg);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.tiptap ul,
|
|
28
|
+
.tiptap ol {
|
|
29
|
+
padding: 0 1rem;
|
|
30
|
+
margin: 1.25rem 1rem 1.25rem 0.4rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.tiptap ul li p,
|
|
34
|
+
.tiptap ol li p {
|
|
35
|
+
margin-top: 0.25em;
|
|
36
|
+
margin-bottom: 0.25em;
|
|
37
|
+
}
|
|
38
|
+
.tiptap ul {
|
|
39
|
+
list-style-type: disc;
|
|
40
|
+
}
|
|
41
|
+
.tiptap ol {
|
|
42
|
+
list-style-type: decimal;
|
|
43
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { default as Images } from "./Nodes/Images/images.svelte";
|
|
2
|
+
export { default as Headings } from "./Nodes/Headings/heading.svelte";
|
|
3
|
+
export { default as TextAlign } from "./Nodes/TextAlign/textAlign.svelte";
|
|
4
|
+
export { default as TextColor } from "./Nodes/TextColor/textColor.svelte";
|
|
5
|
+
export { default as Youtube } from "./Nodes/Youtube/youtube.svelte";
|
|
6
|
+
export { default as Lists } from "./Nodes/Lists/lists.svelte";
|
|
7
|
+
export { default as TextFormatting } from "./Marks/TextFormatting/textFormatting.svelte";
|
|
8
|
+
export { default as Links } from "./Marks/Links/links.svelte";
|
|
9
|
+
export { default as History } from "./Nodes/History/history.svelte";
|
|
10
|
+
export { default as Save } from "./save.svelte";
|
|
11
|
+
export { insertImageAndMoveCursor } from "./Hooks/insertImage.js";
|
|
12
|
+
export { addYoutubeVideo } from "./Hooks/insertYoutube.js";
|
|
13
|
+
export { extractImagesFromJSON } from "./Hooks/extractImage.js";
|
|
14
|
+
export { exractContent } from "./Hooks/extractContent.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
//Nodes
|
|
2
|
+
export {default as Images} from './Nodes/Images/images.svelte';
|
|
3
|
+
export {default as Headings} from './Nodes/Headings/heading.svelte';
|
|
4
|
+
export {default as TextAlign} from './Nodes/TextAlign/textAlign.svelte';
|
|
5
|
+
export {default as TextColor} from './Nodes/TextColor/textColor.svelte';
|
|
6
|
+
export {default as Youtube} from './Nodes/Youtube/youtube.svelte';
|
|
7
|
+
export {default as Lists} from './Nodes/Lists/lists.svelte';
|
|
8
|
+
|
|
9
|
+
//Marks
|
|
10
|
+
export {default as TextFormatting} from './Marks/TextFormatting/textFormatting.svelte';
|
|
11
|
+
export {default as Links} from './Marks/Links/links.svelte';
|
|
12
|
+
|
|
13
|
+
//functionality
|
|
14
|
+
export {default as History} from './Nodes/History/history.svelte';
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
//Export
|
|
18
|
+
export {default as Save} from './save.svelte';
|
|
19
|
+
//Hooks
|
|
20
|
+
export {insertImageAndMoveCursor} from './Hooks/insertImage.js';
|
|
21
|
+
export {addYoutubeVideo} from './Hooks/insertYoutube.js';
|
|
22
|
+
export {extractImagesFromJSON} from './Hooks/extractImage.js';
|
|
23
|
+
export {exractContent} from './Hooks/extractContent.js';
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { onMount } from 'svelte';
|
|
3
|
+
import { fileInputStore, User, isLoggedIn, setToastMessage } from '../../../index.js';
|
|
4
|
+
import Previews from './previews.svelte';
|
|
5
|
+
|
|
6
|
+
export let processing: boolean;
|
|
7
|
+
const tabs: { name: 'Documents'| 'Music' | 'Pictures' | 'Videos'; icon: string }[] = [
|
|
8
|
+
{ name: 'Documents', icon: 'fa fa-file-o' },
|
|
9
|
+
{ name: 'Music', icon: 'fa fa-music' },
|
|
10
|
+
{ name: 'Pictures', icon: 'fa fa-file-image-o' },
|
|
11
|
+
{ name: 'Videos', icon: 'fa fa-film' }
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
$: if ($fileInputStore.disabledMenuItem?.includes($fileInputStore.activeMenu)) {
|
|
15
|
+
const firstAvailable = tabs.find(tab => !$fileInputStore.disabledMenuItem?.includes(tab.name));
|
|
16
|
+
if (firstAvailable) $fileInputStore.activeMenu = firstAvailable.name;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
type MediaItem = {
|
|
20
|
+
id: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
type MediaResponse = {
|
|
24
|
+
Audio: MediaItem[];
|
|
25
|
+
Documents: MediaItem[];
|
|
26
|
+
Images: MediaItem[];
|
|
27
|
+
Videos: MediaItem[];
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
let media: MediaResponse | null = null;
|
|
31
|
+
|
|
32
|
+
async function loadMedia(){
|
|
33
|
+
if (!$User.userId) return;
|
|
34
|
+
if(!$fileInputStore.serverGetUrl) return;
|
|
35
|
+
fileInputStore.update(store => ({
|
|
36
|
+
...store,
|
|
37
|
+
requestReload: false
|
|
38
|
+
}));
|
|
39
|
+
try {
|
|
40
|
+
processing = true;
|
|
41
|
+
const params = new URLSearchParams({
|
|
42
|
+
isLoggedIn: String($isLoggedIn),
|
|
43
|
+
userId: $User.userId
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const res = await fetch(`${$fileInputStore.serverGetUrl}?${params.toString()}`);
|
|
47
|
+
|
|
48
|
+
const data = await res.json();
|
|
49
|
+
|
|
50
|
+
if (!res.ok) {
|
|
51
|
+
//console.log('Error fetching media:', data);
|
|
52
|
+
setToastMessage("error", data || "Failed to fetch media.");
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
media = data;
|
|
56
|
+
} catch (e) {
|
|
57
|
+
console.error("catch error:", e);
|
|
58
|
+
setToastMessage("error", "An error occurred while fetching media.");
|
|
59
|
+
} finally {
|
|
60
|
+
processing = false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
onMount(async () => {
|
|
65
|
+
await loadMedia();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
$: if ($fileInputStore.requestReload) loadMedia();
|
|
69
|
+
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<style>
|
|
73
|
+
#sierra-cloud-store .icon-active {
|
|
74
|
+
background-color: var(--menu-icon-active-bg);
|
|
75
|
+
}
|
|
76
|
+
</style>
|
|
77
|
+
<main id="sierra-cloud-store" style="display: flex; gap: 1rem; height: 100%; min-height: 300px;">
|
|
78
|
+
<nav style="display: flex; flex-direction: column; gap: 0.5rem; padding-top: 1rem; background-color: var(--background); border-bottom-left-radius:5px;">
|
|
79
|
+
{#each tabs as tab}
|
|
80
|
+
<button
|
|
81
|
+
on:click={() =>
|
|
82
|
+
fileInputStore.update(store =>({
|
|
83
|
+
...store,
|
|
84
|
+
activeMenu: tab.name
|
|
85
|
+
}))
|
|
86
|
+
}
|
|
87
|
+
style="width:100%; padding: 0.1rem 0.5rem; {$fileInputStore.disabledMenuItem?.includes(tab.name) ? 'display: none;' : 'display: flex;align-items: center; gap: 0.5rem;'}"
|
|
88
|
+
class={`sierra-text-ellipsis ${$fileInputStore.activeMenu === tab.name ? 'icon-active' : ''}`}
|
|
89
|
+
>
|
|
90
|
+
<i class={tab.icon} style="font-size: 10px; color: var(--icon-theme);"></i>
|
|
91
|
+
{tab.name}
|
|
92
|
+
</button>
|
|
93
|
+
{/each}
|
|
94
|
+
</nav>
|
|
95
|
+
<Previews {media} />
|
|
96
|
+
</main>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const CloudStore: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
processing: boolean;
|
|
16
|
+
}, {
|
|
17
|
+
[evt: string]: CustomEvent<any>;
|
|
18
|
+
}, {}, {}, string>;
|
|
19
|
+
type CloudStore = InstanceType<typeof CloudStore>;
|
|
20
|
+
export default CloudStore;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {fileInputStore, LinearProgress, setToastMessage, modalStore, resetFileInputStore} from "../../../index.js";
|
|
3
|
+
import { get } from 'svelte/store';
|
|
4
|
+
export let processing:boolean;
|
|
5
|
+
|
|
6
|
+
const menuItems = [
|
|
7
|
+
{
|
|
8
|
+
id: 'cloud',
|
|
9
|
+
label: 'Cloud',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
id: 'upload',
|
|
13
|
+
label: 'Upload',
|
|
14
|
+
},
|
|
15
|
+
] as const;
|
|
16
|
+
|
|
17
|
+
function handleSelect() {
|
|
18
|
+
fileInputStore.update(store => ({
|
|
19
|
+
...store,
|
|
20
|
+
submissionComplete: true,
|
|
21
|
+
uploadModalOpen: false
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
function handleDelete() {
|
|
25
|
+
modalStore.update(store => ({
|
|
26
|
+
...store,
|
|
27
|
+
open: true,
|
|
28
|
+
title: 'Confirm Action',
|
|
29
|
+
content: `Are you sure you want to delete the selected files? This action cannot be undone.`,
|
|
30
|
+
onConfirm: () => {
|
|
31
|
+
deleteSubmissions();
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
async function deleteSubmissions() {
|
|
36
|
+
const store = get(fileInputStore);
|
|
37
|
+
const idsToDelete = store.submissions.map(item => item.id);
|
|
38
|
+
|
|
39
|
+
//Test
|
|
40
|
+
//const idsToDelete = ['f47ac10b-58cc-4372-a567-0e02b2c3d479']
|
|
41
|
+
|
|
42
|
+
if (!idsToDelete || idsToDelete.length === 0) return;
|
|
43
|
+
if (!$fileInputStore.serverDeleteUrl) return;
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
processing = true;
|
|
47
|
+
const response = await fetch($fileInputStore.serverDeleteUrl, {
|
|
48
|
+
method: 'DELETE',
|
|
49
|
+
headers: {
|
|
50
|
+
'Content-Type': 'application/json'
|
|
51
|
+
},
|
|
52
|
+
body: JSON.stringify({ id: idsToDelete })
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const data = await response.json();
|
|
56
|
+
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
//console.error('Delete request failed:', data);
|
|
59
|
+
setToastMessage('error', data || 'Failed to delete files.');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
data.forEach((item: { id: string; status: string; code: number }) => {
|
|
64
|
+
if (item.code === 404) {
|
|
65
|
+
setToastMessage('error', `Failed to delete file with ID: ${item.id} - ${item.status}`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
processing = false;
|
|
69
|
+
fileInputStore.update(store => ({
|
|
70
|
+
...store,
|
|
71
|
+
submissions: [],
|
|
72
|
+
requestReload: true
|
|
73
|
+
}));
|
|
74
|
+
|
|
75
|
+
} catch (error) {
|
|
76
|
+
setToastMessage('error', `Error deleting files: ${error}`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
</script>
|
|
80
|
+
<style>
|
|
81
|
+
.file-picker-controls {
|
|
82
|
+
display: flex;
|
|
83
|
+
flex-wrap: wrap;
|
|
84
|
+
justify-content: space-between;
|
|
85
|
+
gap : 1rem;
|
|
86
|
+
width: 100%;
|
|
87
|
+
padding: 0.5rem 1rem;
|
|
88
|
+
border-top-left-radius: 5px;
|
|
89
|
+
border-top-right-radius: 5px;
|
|
90
|
+
background-color: var(--background-tertiary);
|
|
91
|
+
}
|
|
92
|
+
#file-picker-controls i{
|
|
93
|
+
font-size: 18px;
|
|
94
|
+
}
|
|
95
|
+
#file-picker-controls button.active{
|
|
96
|
+
padding: 0.2rem 0.5rem;
|
|
97
|
+
border-radius: 3px;
|
|
98
|
+
background-color: var(--text);
|
|
99
|
+
color: var(--background);
|
|
100
|
+
}
|
|
101
|
+
</style>
|
|
102
|
+
<main id="file-picker-controls" style="display: flex; justify-content: space-between; gap:1rem;">
|
|
103
|
+
<div class="file-picker-controls">
|
|
104
|
+
<div style="display: flex; align-items: last baseline; gap:1rem;">
|
|
105
|
+
{#each menuItems as item, index (item.id)}
|
|
106
|
+
<button
|
|
107
|
+
class={$fileInputStore.activeTab === item.id ? 'active' : ''}
|
|
108
|
+
on:click={() => {fileInputStore.update(store => ({ ...store, activeTab: item.id }))}}
|
|
109
|
+
><span>{item.label}</span>
|
|
110
|
+
</button>
|
|
111
|
+
{/each}
|
|
112
|
+
</div>
|
|
113
|
+
<div style="display: flex; gap: 2rem; align-items: last baseline;">
|
|
114
|
+
{#if $fileInputStore.submissions.length > 0 && $fileInputStore.activeTab === 'cloud'}
|
|
115
|
+
<button hidden={!$fileInputStore.manage} title="Delete" on:click={handleDelete} style="color: var(--error-bg);" aria-label="Delete submissions"><i class="fa fa-trash-o"></i></button>
|
|
116
|
+
<button hidden={$fileInputStore.manage} title="Select" on:click={handleSelect} style="color: var(--primary-bg);" aria-label="Select submissions"><i class="fa fa-check-circle-o"></i></button>
|
|
117
|
+
{/if}
|
|
118
|
+
<button title="Cancel" on:click={resetFileInputStore} aria-label="Cancel"><i class="fa fa-times-circle"></i></button>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</main>
|
|
122
|
+
{#if processing}<LinearProgress />{/if}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const Controls: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
processing: boolean;
|
|
16
|
+
}, {
|
|
17
|
+
[evt: string]: CustomEvent<any>;
|
|
18
|
+
}, {}, {}, string>;
|
|
19
|
+
type Controls = InstanceType<typeof Controls>;
|
|
20
|
+
export default Controls;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {Backdrop,Wrapper,fileInputStore, FileInput, isLoggedIn, User, setToastMessage} from '../../../index.js'
|
|
3
|
+
import CloudStore from './cloudStore.svelte';
|
|
4
|
+
import Controls from './controls.svelte';
|
|
5
|
+
|
|
6
|
+
let processing: boolean = false;
|
|
7
|
+
|
|
8
|
+
async function handleUpload() {
|
|
9
|
+
if(!$User.userId || !$fileInputStore.r2_key || $fileInputStore.selectedFiles.length === 0 || !$fileInputStore.serverUploadUrl) return;
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
processing = true;
|
|
13
|
+
const formData = new FormData();
|
|
14
|
+
|
|
15
|
+
$fileInputStore.selectedFiles.forEach(file => formData.append('files', file));
|
|
16
|
+
formData.append('r2_key', $fileInputStore.r2_key);
|
|
17
|
+
formData.append('is_loggedin', $isLoggedIn.toString());
|
|
18
|
+
formData.append('userid', $User.userId);
|
|
19
|
+
|
|
20
|
+
const res = await fetch($fileInputStore.serverUploadUrl, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
body: formData
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const data = await res.json();
|
|
26
|
+
|
|
27
|
+
if (!res.ok) {
|
|
28
|
+
setToastMessage('error', data || 'Upload failed' );
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
data.forEach((item: { code: number; original_name: string }) => {
|
|
33
|
+
if (item.code === 500) {
|
|
34
|
+
setToastMessage('error', `Failed to upload file: ${item.original_name} (code: ${item.code})`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
fileInputStore.update(store => {
|
|
39
|
+
store.selectedFiles = [];
|
|
40
|
+
store.activeTab = 'cloud';
|
|
41
|
+
store.requestReload = true;
|
|
42
|
+
return store;
|
|
43
|
+
});
|
|
44
|
+
} catch (err) {
|
|
45
|
+
setToastMessage('error', `Upload failed: ${err}`);
|
|
46
|
+
} finally {
|
|
47
|
+
processing = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
</script>
|
|
51
|
+
|
|
52
|
+
<Backdrop bind:open={$fileInputStore.uploadModalOpen} zIndex={15}>
|
|
53
|
+
<Wrapper maxWidth="700px" minHeight="300px" padding="0px">
|
|
54
|
+
<Controls bind:processing />
|
|
55
|
+
{#if $fileInputStore.activeTab === 'cloud'}
|
|
56
|
+
<CloudStore bind:processing />
|
|
57
|
+
{:else}
|
|
58
|
+
<FileInput bind:processing onclick={handleUpload} />
|
|
59
|
+
{/if}
|
|
60
|
+
</Wrapper>
|
|
61
|
+
</Backdrop>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const FilePicker: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
|
|
15
|
+
[evt: string]: CustomEvent<any>;
|
|
16
|
+
}, {}, {}, string>;
|
|
17
|
+
type FilePicker = InstanceType<typeof FilePicker>;
|
|
18
|
+
export default FilePicker;
|