Loading src/app/App.vue +21 −15 Original line number Diff line number Diff line Loading @@ -5,21 +5,27 @@ const visible = ref<boolean>(false); </script> <template> <Suspense> <div> <router-view /> <div class="fixed top-0 left-0 z-50"> <Button @click.prevent="visible = !visible" label="Menu" iconPos="top" icon="pi pi-bars" severity="secondary" severity="contrast" size="small" @click.prevent="visible = !visible" /> </div> <Drawer v-model:visible="visible"> <template #container="{ closeCallback }"> <BaseSidebarMenu @closeCallback="closeCallback" class="relative z-50" /> <BaseSidebarMenu class="relative z-50" @closeCallback="closeCallback" /> </template> </Drawer> </div> <template #fallback><BaseLoader /></template> </Suspense> </template> <style scoped></style> src/app/assets/main.css +20 −0 Original line number Diff line number Diff line Loading @@ -199,3 +199,23 @@ label { legend { display: block; } ::-webkit-scrollbar { width: 10px; } /* Track */ ::-webkit-scrollbar-track { background: #484848; } /* Handle */ ::-webkit-scrollbar-thumb { border-radius: 5px; background: #0055ff; transition: all 0.5s ease; } /* Handle on hover */ ::-webkit-scrollbar-thumb:hover { background: #0033ff; } src/app/interfaces/entities.ts +12 −12 Original line number Diff line number Diff line Loading @@ -3,18 +3,18 @@ import type { IEntity } from '@/app/interfaces/environment'; export interface ITable extends IEntity { entity_type: 'table'; entity_uuid: string; title?: string; text?: string; title?: string | null; text?: string | null; table_columns: ITableColumn[]; table_data: { [key: string]: any; [key: string]: never; }[]; } interface ITableColumn { export interface ITableColumn { column_uuid: string; name: string; type: ITableColumnTypes; data: any; data: never; } type ITableColumnTypes = | 'text' Loading @@ -29,7 +29,7 @@ type ITableColumnTypes = export interface IText extends IEntity { entity_type: 'text'; entity_uuid: string; title?: string; title?: string | null; text: string; font_size?: '16' | '20' | '24' | '40' | '64'; paragraph_size?: 'full' | 'half'; Loading @@ -40,12 +40,12 @@ export interface IText extends IEntity { export interface IImage extends IEntity { entity_type: 'image'; entity_uuid: string; title?: string; text?: string; font_size?: '16' | '20' | '24' | '40' | '64'; paragraph_size?: 'full' | 'half'; text_position?: 'left' | 'right'; image_url: string; title?: string | null; text?: string | null; font_size?: '16' | '20' | '24' | '40' | '64' | null; paragraph_size?: 'full' | 'half' | null; text_position?: 'left' | 'right' | null; imageUrl: string; image_width: number; image_height: number; image_scale: string; Loading src/app/interfaces/environment.ts +13 −9 Original line number Diff line number Diff line import type { ITableColumn } from '@/app/interfaces/entities'; export interface ISheet { sheet_uuid: string; title: string; Loading @@ -11,20 +13,22 @@ export interface IEntity { user_nick_name?: string; entity_order?: number; entity_type: string; title?: string; text?: string; font_size?: string; paragraph_size?: string; text_position?: string; image_blob?: string; image_url?: string; title?: string | null; text?: string | null; font_size?: string | null; paragraph_size?: string | null; text_position?: string | null; image_buffer?: string; imageUrl?: string; image_width?: number; image_height?: number; entity_position?: string; entity_title_position?: string; image_scale?: string; table_columns?: string; table_data?: string; table_columns?: ITableColumn[]; table_data?: { [key: string]: never; }[]; } export type TThemes = Loading src/components/CreateEntityMenu.vue +19 −19 Original line number Diff line number Diff line <script setup lang="ts"> import { v4 as uuidv4 } from 'uuid'; import { useFileDialog } from '@vueuse/core'; import { useFileDialog, useWindowSize } from '@vueuse/core'; import { useAuthorizationStore } from '@/app/stores/authorization'; import { useFilesWebsocketStore } from '@/app/stores/filesWebsocket'; const emit = defineEmits(['addEntity']); const emit = defineEmits(['createEntity']); const { open: uploadFile, onChange } = useFileDialog({ accept: 'image/*', reset: true }); const authorizationStore = useAuthorizationStore(); const userNickName = computed(() => authorizationStore.userNickName); const addImage = async (files: FileList) => { let image = new Image(); const imageUuid = uuidv4(); // const file = files[0]; // const reader = new FileReader(); // reader.readAsDataURL(file); // const file = new FormData(); if (!files[0]) return; // const mediaSource = new MediaSource(); // const url = const url = URL.createObjectURL(files[0]); image.src = url; // file.set('file', files[0]); // reader.addEventListener('load', () => { // image.src = String(reader.result); // }); image.onload = async () => { console.log('url: ', url); const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(url); const response = await fetch(url); const blob = await response.blob(); const buffer = await blob.arrayBuffer(); console.log('blob: ', blob); emit('addEntity', { const { width: windowWidth } = useWindowSize(); const maxWidth = windowWidth.value - 128; if (image.width > maxWidth) { image.height = Math.floor(maxWidth / image.width) * image.height; image.width = maxWidth; } emit('createEntity', { entity_type: 'image', entity_uuid: imageUuid, image_blob: buffer, image_buffer: buffer, entity_position: 'left', entity_title_position: 'center', image_width: image.width, Loading @@ -54,7 +54,7 @@ const speedDialItems = ref([ label: 'Text', icon: 'pi pi-pencil', command: () => { emit('addEntity', { emit('createEntity', { entity_type: 'text', entity_uuid: uuidv4(), text: '', Loading @@ -73,7 +73,7 @@ const speedDialItems = ref([ label: 'Table', icon: 'pi pi-table', command: () => { emit('addEntity', { emit('createEntity', { entity_type: 'table', entity_uuid: uuidv4(), table_columns: [ Loading @@ -100,7 +100,7 @@ const speedDialItems = ref([ <SpeedDial :model="speedDialItems" direction="right" :buttonProps="{ severity: 'info', rounded: true }" :button-props="{ severity: 'info', rounded: true }" style="position: absolute; left: 5%; top: 0" > <template #item="{ item, toggleCallback }"> Loading Loading
src/app/App.vue +21 −15 Original line number Diff line number Diff line Loading @@ -5,21 +5,27 @@ const visible = ref<boolean>(false); </script> <template> <Suspense> <div> <router-view /> <div class="fixed top-0 left-0 z-50"> <Button @click.prevent="visible = !visible" label="Menu" iconPos="top" icon="pi pi-bars" severity="secondary" severity="contrast" size="small" @click.prevent="visible = !visible" /> </div> <Drawer v-model:visible="visible"> <template #container="{ closeCallback }"> <BaseSidebarMenu @closeCallback="closeCallback" class="relative z-50" /> <BaseSidebarMenu class="relative z-50" @closeCallback="closeCallback" /> </template> </Drawer> </div> <template #fallback><BaseLoader /></template> </Suspense> </template> <style scoped></style>
src/app/assets/main.css +20 −0 Original line number Diff line number Diff line Loading @@ -199,3 +199,23 @@ label { legend { display: block; } ::-webkit-scrollbar { width: 10px; } /* Track */ ::-webkit-scrollbar-track { background: #484848; } /* Handle */ ::-webkit-scrollbar-thumb { border-radius: 5px; background: #0055ff; transition: all 0.5s ease; } /* Handle on hover */ ::-webkit-scrollbar-thumb:hover { background: #0033ff; }
src/app/interfaces/entities.ts +12 −12 Original line number Diff line number Diff line Loading @@ -3,18 +3,18 @@ import type { IEntity } from '@/app/interfaces/environment'; export interface ITable extends IEntity { entity_type: 'table'; entity_uuid: string; title?: string; text?: string; title?: string | null; text?: string | null; table_columns: ITableColumn[]; table_data: { [key: string]: any; [key: string]: never; }[]; } interface ITableColumn { export interface ITableColumn { column_uuid: string; name: string; type: ITableColumnTypes; data: any; data: never; } type ITableColumnTypes = | 'text' Loading @@ -29,7 +29,7 @@ type ITableColumnTypes = export interface IText extends IEntity { entity_type: 'text'; entity_uuid: string; title?: string; title?: string | null; text: string; font_size?: '16' | '20' | '24' | '40' | '64'; paragraph_size?: 'full' | 'half'; Loading @@ -40,12 +40,12 @@ export interface IText extends IEntity { export interface IImage extends IEntity { entity_type: 'image'; entity_uuid: string; title?: string; text?: string; font_size?: '16' | '20' | '24' | '40' | '64'; paragraph_size?: 'full' | 'half'; text_position?: 'left' | 'right'; image_url: string; title?: string | null; text?: string | null; font_size?: '16' | '20' | '24' | '40' | '64' | null; paragraph_size?: 'full' | 'half' | null; text_position?: 'left' | 'right' | null; imageUrl: string; image_width: number; image_height: number; image_scale: string; Loading
src/app/interfaces/environment.ts +13 −9 Original line number Diff line number Diff line import type { ITableColumn } from '@/app/interfaces/entities'; export interface ISheet { sheet_uuid: string; title: string; Loading @@ -11,20 +13,22 @@ export interface IEntity { user_nick_name?: string; entity_order?: number; entity_type: string; title?: string; text?: string; font_size?: string; paragraph_size?: string; text_position?: string; image_blob?: string; image_url?: string; title?: string | null; text?: string | null; font_size?: string | null; paragraph_size?: string | null; text_position?: string | null; image_buffer?: string; imageUrl?: string; image_width?: number; image_height?: number; entity_position?: string; entity_title_position?: string; image_scale?: string; table_columns?: string; table_data?: string; table_columns?: ITableColumn[]; table_data?: { [key: string]: never; }[]; } export type TThemes = Loading
src/components/CreateEntityMenu.vue +19 −19 Original line number Diff line number Diff line <script setup lang="ts"> import { v4 as uuidv4 } from 'uuid'; import { useFileDialog } from '@vueuse/core'; import { useFileDialog, useWindowSize } from '@vueuse/core'; import { useAuthorizationStore } from '@/app/stores/authorization'; import { useFilesWebsocketStore } from '@/app/stores/filesWebsocket'; const emit = defineEmits(['addEntity']); const emit = defineEmits(['createEntity']); const { open: uploadFile, onChange } = useFileDialog({ accept: 'image/*', reset: true }); const authorizationStore = useAuthorizationStore(); const userNickName = computed(() => authorizationStore.userNickName); const addImage = async (files: FileList) => { let image = new Image(); const imageUuid = uuidv4(); // const file = files[0]; // const reader = new FileReader(); // reader.readAsDataURL(file); // const file = new FormData(); if (!files[0]) return; // const mediaSource = new MediaSource(); // const url = const url = URL.createObjectURL(files[0]); image.src = url; // file.set('file', files[0]); // reader.addEventListener('load', () => { // image.src = String(reader.result); // }); image.onload = async () => { console.log('url: ', url); const filesWebsocketStore = useFilesWebsocketStore(); filesWebsocketStore.saveImageUrl(url); const response = await fetch(url); const blob = await response.blob(); const buffer = await blob.arrayBuffer(); console.log('blob: ', blob); emit('addEntity', { const { width: windowWidth } = useWindowSize(); const maxWidth = windowWidth.value - 128; if (image.width > maxWidth) { image.height = Math.floor(maxWidth / image.width) * image.height; image.width = maxWidth; } emit('createEntity', { entity_type: 'image', entity_uuid: imageUuid, image_blob: buffer, image_buffer: buffer, entity_position: 'left', entity_title_position: 'center', image_width: image.width, Loading @@ -54,7 +54,7 @@ const speedDialItems = ref([ label: 'Text', icon: 'pi pi-pencil', command: () => { emit('addEntity', { emit('createEntity', { entity_type: 'text', entity_uuid: uuidv4(), text: '', Loading @@ -73,7 +73,7 @@ const speedDialItems = ref([ label: 'Table', icon: 'pi pi-table', command: () => { emit('addEntity', { emit('createEntity', { entity_type: 'table', entity_uuid: uuidv4(), table_columns: [ Loading @@ -100,7 +100,7 @@ const speedDialItems = ref([ <SpeedDial :model="speedDialItems" direction="right" :buttonProps="{ severity: 'info', rounded: true }" :button-props="{ severity: 'info', rounded: true }" style="position: absolute; left: 5%; top: 0" > <template #item="{ item, toggleCallback }"> Loading