Skip to content

Commit

Permalink
Merge pull request #13 from Joery-M/8-sl-ui-add-ability-to-change-pro…
Browse files Browse the repository at this point in the history
…ject-name-from-project-list

8 sl UI add ability to change project name from project list
  • Loading branch information
Joery-M authored Apr 19, 2024
2 parents d876dd6 + 903d079 commit fe3feb8
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 44 deletions.
23 changes: 6 additions & 17 deletions packages/safelight/src/components/Editor/Library/LibraryItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -72,23 +72,12 @@ const menuItems = ref<MenuItem[]>([
}
]);
// My god
// TODO: Not this
const hasItemInTimeline = computed(() => {
console.log('A');
return project.project
? project.project.timelines.some(
(t) =>
t.isSimpleTimeline() &&
t.items.some(
(i) =>
i.isBaseTimelineItem() &&
i.isVideo() &&
i.media.value?.id == props.item.id
)
)
: false;
});
const hasItemInTimeline = computed(
() =>
project.project &&
project.project.isSimpleProject() &&
project.project.usesMedia(props.item)
);
const alertt = (text: string) => window.alert(text);
Expand Down
53 changes: 53 additions & 0 deletions packages/safelight/src/components/InplaceRename.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<slot v-if="!isOpen" name="default">
<label @dblclick="open()">{{ value }}</label>
</slot>
<slot v-else name="content" :cur-value="curValue" :close="close">
<div v-focustrap>
<InputText
v-model="curValue"
autofocus
@focusout="close()"
@change="sendValue()"
@keyup.enter="sendValue(true)"
@keyup.escape="close()"
/>
</div>
</slot>
</template>

<script lang="ts" setup>
import type InputText from 'primevue/inputtext';
defineSlots<{
default: [];
content: {
close: () => void;
curValue: string;
};
}>();
const props = defineProps<{
value: string;
closeOnChange?: boolean;
}>();
const isOpen = ref(false);
const curValue = ref(props.value);
const emit = defineEmits<{
change: [string];
}>();
function open() {
isOpen.value = true;
}
function close() {
isOpen.value = false;
}
function sendValue(forceClose = false) {
emit('change', curValue.value);
if (props.closeOnChange || forceClose) close();
}
</script>
18 changes: 16 additions & 2 deletions packages/safelight/src/components/Menu/ProjectList/ProjectList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
/>
</div>
</template>
<Column field="name" header="Project" />
<Column field="name" header="Project">
<template #body="{ data }: { data: StoredProject }">
<InplaceRename :value="data.name" @change="(ev) => setProjectName(ev, data)" />
</template>
</Column>
<Column field="type" header="Type" />
<Column header="Modified">
<template #body="slotProps">
Expand All @@ -32,6 +36,7 @@
</template>

<script setup lang="ts">
import InplaceRename from '@/components/InplaceRename.vue';
import { Storage, type StoredProject } from '@safelight/shared/base/Storage';
import { DateTime } from 'luxon';
import type { MenuItem } from 'primevue/menuitem';
Expand Down Expand Up @@ -69,6 +74,15 @@ function loadList() {
function formatDateTime(dt: string) {
const date = DateTime.fromISO(dt).toLocal();
return date.toLocaleString({ dateStyle: 'long', timeStyle: 'short' });
return date.toLocaleString({
dateStyle: 'long',
timeStyle: 'short'
});
}
async function setProjectName(newName: string, project: StoredProject) {
const storage = await getStorageControllerForProject(project);
await storage?.UpdateStoredProject({ id: project.id, name: newName });
loadList();
}
</script>
2 changes: 2 additions & 0 deletions packages/safelight/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ConfirmationService from 'primevue/confirmationservice';
import 'primevue/resources/primevue.min.css';
import 'primevue/resources/themes/aura-dark-amber/theme.css';
import Tooltip from 'primevue/tooltip';
import FocusTrap from 'primevue/focustrap';

import './style.scss';

Expand All @@ -29,5 +30,6 @@ app.use(ConfirmationService);

// Directives
app.directive('tooltip', Tooltip);
app.directive('focustrap', FocusTrap);

app.mount('#app');
37 changes: 22 additions & 15 deletions packages/safelight/src/stores/useProject.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { router } from '@/main';
import type BaseProject from '@safelight/shared/base/Project';
import { Storage, type StoredProject } from '@safelight/shared/base/Storage';
import BaseStorageController, { Storage, type StoredProject } from '@safelight/shared/base/Storage';
import MediaManager from '@safelight/shared/Storage/MediaManager';

export const useProject = defineStore('Project', () => {
Expand Down Expand Up @@ -79,25 +79,32 @@ async function newSimpleProject() {
await toEditor();
}

export async function getStorageControllerForProject(
project: StoredProject
): Promise<BaseStorageController | undefined> {
if (project.type == 'Simple') {
return new (await import('@safelight/shared/Storage/IndexedDbStorage')).default();
} else {
console.error('Project type not supported');
}
}

async function openProject(selectedProject: StoredProject) {
if (selectedProject.type == 'Simple') {
const IndexedDbStorageController = (
await import('@safelight/shared/Storage/IndexedDbStorage')
).default;
const storageType = await getStorageControllerForProject(selectedProject);
if (!storageType) {
throw new Error('Could not find storage controller for project type');
}

const projectStore = useProject();
Storage.setStorage(new IndexedDbStorageController());
const projectStore = useProject();
Storage.setStorage(storageType);

const project = await Storage.getStorage().LoadProject(selectedProject.id);
const project = await Storage.getStorage().LoadProject(selectedProject.id);

if (project) {
projectStore.setProject(project);
await toEditor();
} else {
console.error('Could not load project');
}
if (project) {
projectStore.setProject(project);
await toEditor();
} else {
console.error('Project type not supported');
console.error('Could not load project');
}
}

Expand Down
45 changes: 35 additions & 10 deletions packages/shared/src/Storage/IndexedDbStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,21 @@ export default class IndexedDbStorageController extends BaseStorageController {

private db = new SafelightIndexedDB();

async SaveProject(project: BaseProject): Promise<SaveResults> {
async SaveProject(project: BaseProject | StoredProject): Promise<SaveResults> {
const existingProject = await this.db.project.get({ id: project.id });

const storableProject: StoredProject = {
id: project.id,
name: project.name,
type: project.type,
media: project.media.map((m) => m.id).filter((id) => id !== undefined),
timelines: project.timelines.map((m) => m.id),
updated: DateTime.now().toISO(),
created: existingProject?.created ?? DateTime.now().toISO()
};
const storableProject: StoredProject =
'updated' in project
? project
: {
id: project.id,
name: project.name,
type: project.type,
media: project.media.map((m) => m.id).filter((id) => id !== undefined),
timelines: project.timelines.map((m) => m.id),
updated: DateTime.now().toISO(),
created: existingProject?.created ?? DateTime.now().toISO()
};

try {
await this.db.project.put(storableProject, project.id);
Expand Down Expand Up @@ -78,6 +81,28 @@ export default class IndexedDbStorageController extends BaseStorageController {
}
});
}
async UpdateStoredProject(
project: Partial<StoredProject> & Pick<StoredProject, 'id'>
): Promise<SaveResults> {
const existingProject = await this.db.project.get({ id: project.id });

// Remove created so it can't be overridden
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { created, ...restProject } = project;

const storableProject: StoredProject = {
...existingProject,
...(restProject as StoredProject),
updated: DateTime.now().toISO()
};

try {
await this.db.project.put(storableProject, project.id);
return 'Success';
} catch (error: any) {
return error.toString();
}
}
static getProjects(): Promise<StoredProject[]> {
return new Promise(async (resolve) => {
const db = new SafelightIndexedDB();
Expand Down
3 changes: 3 additions & 0 deletions packages/shared/src/base/Storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export default abstract class BaseStorageController {

abstract SaveProject(project: BaseProject): Promise<SaveResults>;
abstract LoadProject(projectId: string): Promise<BaseProject | undefined>;
abstract UpdateStoredProject(
project: Partial<StoredProject> & Pick<StoredProject, 'id'>
): Promise<SaveResults>;
static getProjects: () => Promise<StoredProject[]>;

abstract SaveMedia(media: StoredMedia): Promise<SaveResults>;
Expand Down

0 comments on commit fe3feb8

Please sign in to comment.