Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

245 shared refactor media in local storage #262

Merged
merged 22 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
cb19a50
refactor(Shared): :construction: Partially implemented new media stru…
Joery-M Sep 28, 2024
050b786
refactor(Shared): :construction: Further refactoring
Joery-M Oct 1, 2024
a5ab91d
feat(Localization): :globe_with_meridians: Made notification use tran…
Joery-M Oct 1, 2024
ee366bd
Merge remote-tracking branch 'origin/main' into 245-shared-refactor-m…
Joery-M Oct 1, 2024
89ea996
Merge remote-tracking branch 'origin/main' into 245-shared-refactor-m…
Joery-M Oct 1, 2024
82f7ef5
Merge remote-tracking branch 'origin/main' into 245-shared-refactor-m…
Joery-M Oct 11, 2024
8af35aa
refactor(Shared): :art: Changed casing on methods, Implemented media …
Joery-M Oct 11, 2024
7a36a96
refactor(Localization): :art: Refactored i18n files to match the form…
Joery-M Oct 12, 2024
8fe1f04
chore(Demuxing): :art: Changed demuxers to be matched based on MimeMa…
Joery-M Oct 13, 2024
21d46bc
feat(Demuxing): :sparkles: Implemented demuxing into storage
Joery-M Oct 13, 2024
85a67c7
refactor(Media): :poop: Made loading chunks simpler
Joery-M Oct 14, 2024
1f06eaa
refactor(Shared): :building_construction: Renamed demuxers
Joery-M Oct 14, 2024
f3a8e09
chore(Media): :label: Updated MediaFileVideoTrack, needs implementation
Joery-M Oct 14, 2024
8d4d30d
feat(Demuxing): :art: Added more info to tracks
Joery-M Oct 14, 2024
e583ad7
Merge remote-tracking branch 'origin/main' into 245-shared-refactor-m…
Joery-M Oct 14, 2024
86c7b39
feat: :construction: Partially added TreeTable for inspecting stored …
Joery-M Oct 14, 2024
327f6a6
chore(Localization): :rotating_light: Fixed some raw text
Joery-M Oct 14, 2024
038157d
fix(UI): :bug: Fixed notification body text
Oct 15, 2024
2daa205
fix(UI): :bug: Fixed paths on dev
Oct 15, 2024
736f8f6
test(Shared): :white_check_mark: Fixed tests
Oct 15, 2024
e938e49
feat: :construction: Partially implemented deletion of media
Oct 15, 2024
69b7c2f
feat(Demuxing): :technologist: Finished media overview
Oct 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"test:tswebm": "cd packages/tswebm && pnpm test:run",
"dev": "cd packages/safelight && pnpm dev",
"dev:darkroom": "pnpm build:packages && cd packages/darkroom && pnpm dev:web",
"lint": "pnpm run \"/lint:\"/",
"lint": "pnpm lint:prettier && pnpm lint:eslint",
"lint:prettier": "prettier . --write --ignore-path .gitignore --ignore-path ./packages/safelight/.gitignore --ignore-path .prettierignore",
"lint:eslint": "eslint ./packages/**/*{.ts,.js,.vue}"
},
Expand Down
3 changes: 2 additions & 1 deletion packages/safelight/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
/typed-router.d.ts

# Generated items
/src/generated/*
/src/generated/*
/types/i18n.d.ts
6 changes: 3 additions & 3 deletions packages/safelight/buildscripts/vite-plugin-generate-i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ async function compileTypes({ localesDir: dir, outputFile: output }: Options) {
allFiles,
...(await Promise.all(files.map(async (path) => JSON.parse(await readFile(path, 'utf-8')))))
);
const { localeSettings, ...messages } = allFiles ?? {};

// If no messages, back out
if (!('messages' in allFiles)) {
if (!messages) {
return;
}

Expand All @@ -60,7 +60,7 @@ declare module 'vue-i18n' {

// Add JSON file, and replace all values with "string"
let jsonRes = JSON.stringify(
allFiles.messages,
messages,
(_, value) => (typeof value == 'object' ? value : 'string'),
4
);
Expand Down
84 changes: 49 additions & 35 deletions packages/safelight/src/components/Editor/Library/Library.vue
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
<InputGroupAddon class="p-0">
<PhMagnifyingGlass />
</InputGroupAddon>
<InputText v-model="search" placeholder="Search"> </InputText>
<InputText v-model="search" :placeholder="$t('general.actions.search')">
</InputText>
</InputGroup>
<InputGroup>
<Button
Expand All @@ -47,18 +48,14 @@
outlined
severity="secondary"
:title="
$t(
sortDescending
? 'general.actions.sortAscending'
: 'general.actions.sortDescending'
)
sortDescending
? $t('general.actions.sortAscending')
: $t('general.actions.sortDescending')
"
:aria-label="
$t(
sortDescending
? 'general.actions.sortAscending'
: 'general.actions.sortDescending'
)
sortDescending
? $t('general.actions.sortAscending')
: $t('general.actions.sortDescending')
"
@click="sortDescending = !sortDescending"
>
Expand All @@ -71,7 +68,13 @@
v-model="sortBy"
style="line-height: 1.2"
:aria-label="$t('general.actions.sortBy')"
:options="['Name', 'Duration', 'File type']"
option-label="label"
option-value="value"
:options="[
{ label: $t('general.descriptions.name'), value: 'name' },
{ label: $t('general.descriptions.duration'), value: 'duration' },
{ label: $t('general.descriptions.fileType'), value: 'fileType' }
]"
/>
</InputGroup>
</template>
Expand All @@ -88,7 +91,7 @@
</template>
</Toolbar>
</template>
<template #grid="{ items }: { items: Media[] }">
<template #grid="{ items }: { items: MediaItem[] }">
<div
class="flex h-full select-none flex-wrap justify-center overflow-y-auto"
role="grid"
Expand Down Expand Up @@ -150,40 +153,50 @@
data-key="id"
>
<Column header="Type" body-class="px-0">
<template #body="{ data }: { data: Media }">
<template #body="{ data }: { data: MediaItem }">
<div class="flex gap-2 pl-2">
<PhVideoCamera
v-if="data.isOfType(MediaType.Video)"
v-if="data.isOfType(MediaSourceType.Video)"
weight="bold"
:aria-label="$t('media.attrs.video')"
/>
<PhSpeakerHigh
v-if="data.isOfType(MediaType.Audio)"
v-if="data.isOfType(MediaSourceType.Audio)"
weight="bold"
:aria-label="$t('media.attrs.audio')"
/>
<PhSubtitles
v-if="data.isOfType(MediaType.Text)"
v-if="data.isOfType(MediaSourceType.Subtitles)"
weight="bold"
:aria-label="$t('media.attrs.subtitles')"
/>
<PhImage
v-if="data.isOfType(MediaType.Image)"
v-if="data.isOfType(MediaSourceType.Image)"
weight="bold"
:aria-label="$t('media.attrs.image')"
/>
<PhFilmStrip
v-if="data.isOfType(MediaSourceType.Special)"
weight="bold"
:aria-label="$t('media.attrs.timeline')"
/>
<PhSparkle
v-if="data.isOfType(MediaSourceType.Special)"
weight="bold"
:aria-label="$t('media.attrs.special')"
/>
</div>
</template>
</Column>
<Column field="name.value" :header="$t('general.descriptions.name')" sortable />
<Column field="duration.value" :header="$t('general.descriptions.duration')" sortable>
<template #body="{ data }: { data: Media }">
<template v-if="data.isOfType(MediaType.Image)">
<template #body="{ data }: { data: MediaItem }">
<template v-if="data.isOfType(MediaSourceType.Image)">
{{ Timecode.toFormattedTimecode(5000) }}
</template>
<template v-else>
<!-- <template v-else>
{{ Timecode.toFormattedTimecode(data.duration.value * 1000) }}
</template>
</template> -->
</template>
</Column>
<template #header>
Expand All @@ -204,7 +217,8 @@
<InputGroupAddon class="p-0">
<PhMagnifyingGlass />
</InputGroupAddon>
<InputText v-model="search" placeholder="Search"> </InputText>
<InputText v-model="search" :placeholder="$t('general.actions.search')">
</InputText>
</InputGroup>
</template>
<template #end>
Expand Down Expand Up @@ -239,19 +253,21 @@
<script setup lang="ts">
import { CurrentProject } from '@/stores/currentProject';
import {
PhFilmStrip,
PhImage,
PhList,
PhMagnifyingGlass,
PhPlus,
PhSortAscending,
PhSortDescending,
PhSparkle,
PhSpeakerHigh,
PhSquaresFour,
PhSubtitles,
PhVideoCamera
} from '@phosphor-icons/vue';
import { ProjectFeatures } from '@safelight/shared/base/Project';
import Media, { MediaType } from '@safelight/shared/Media/Media';
import { MediaItem, MediaSourceType } from '@safelight/shared/Media/Media';
import Timecode from '@safelight/shared/Timecode';
import { useDropZone, useFileDialog, watchDebounced } from '@vueuse/core';
import fuzzysearch from 'fuzzysearch';
Expand Down Expand Up @@ -301,18 +317,18 @@ fileDialog.onChange((fileList) => {
});

const search = ref('');
const sortBy = ref<sortOptions>('Name');
const sortBy = ref<sortOptions>('name');
const sortDescending = ref(false);
const layout = ref<string>('grid');
const gridItemSize = ref(176); // 11rem

const sortedAndFiltered = shallowRef<Media[]>([]);
const sortedAndFiltered = shallowRef<MediaItem[]>([]);

// Reset sorting when changing to list
// List has its own sorting
watchEffect(() => {
if (layout.value == 'list') {
sortBy.value = 'Name';
sortBy.value = 'name';
sortDescending.value = false;
}
});
Expand All @@ -336,7 +352,7 @@ function sortAndFilter() {
return true;
}

return fuzzysearch(search.value.toLowerCase(), elem.name.value.toLowerCase());
return fuzzysearch(search.value.toLowerCase(), elem.name.toLowerCase());
});

const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: 'base' });
Expand All @@ -345,16 +361,14 @@ function sortAndFilter() {
const item1 = sortDescending.value ? b : a;
const item2 = sortDescending.value ? a : b;

const ext1 = item1.name.value.split('.').at(-1) ?? 'ZZZ';
const ext2 = item2.name.value.split('.').at(-1) ?? 'ZZZ';
const ext1 = item1.name.split('.').at(-1) ?? 'ZZZ';
const ext2 = item2.name.split('.').at(-1) ?? 'ZZZ';

switch (sortBy.value) {
case 'Duration':
return item1.duration.value - item2.duration.value;
case 'File type':
case 'fileType':
return collator.compare(ext1, ext2);
default:
return collator.compare(item1.name.value, item2.name.value);
return collator.compare(item1.name, item2.name);
}
});

Expand All @@ -367,5 +381,5 @@ function fileDialogOpenDblClick(event: MouseEvent) {
fileDialog.open();
}

type sortOptions = 'Name' | 'Duration' | 'File type';
type sortOptions = 'name' | 'duration' | 'fileType';
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
:style="{
width: size + 'px'
}"
:aria-label="item.name.value"
:aria-label="item.name"
@contextmenu.prevent="
(ev) => {
closeOtherOverlays();
Expand All @@ -18,46 +18,55 @@
class="bg-checkerboard relative flex aspect-video w-full items-center justify-center text-clip rounded-t-md"
>
<img
v-if="item.previewImage.value"
v-if="false"
class="overflow-none max-h-full max-w-full"
:aria-label="'Preview image for ' + item.name.value"
:src="item.previewImage.value"
:aria-label="'Preview image for ' + item.name"
/>
<Skeleton
v-else
class="max-h-full max-w-full rounded-none rounded-t-md"
height="100%"
width="100%"
/>
<div v-if="size >= 96" class="mediaType">
<div v-if="size >= 96 && itemSourceType" class="mediaType">
<PhVideoCamera
v-if="item.isOfType(MediaType.Video)"
v-if="item.isOfType(MediaSourceType.Video)"
weight="bold"
:aria-label="$t('media.attrs.video')"
/>
<PhSpeakerHigh
v-if="item.isOfType(MediaType.Audio)"
v-if="item.isOfType(MediaSourceType.Audio)"
weight="bold"
:aria-label="$t('media.attrs.audio')"
/>
<PhSubtitles
v-if="item.isOfType(MediaType.Text)"
v-if="item.isOfType(MediaSourceType.Timeline)"
weight="bold"
:aria-label="$t('media.attrs.subtitles')"
/>
<PhImage
v-if="item.isOfType(MediaType.Image)"
v-if="item.isOfType(MediaSourceType.Image)"
weight="bold"
:aria-label="$t('media.attrs.image')"
/>
<PhFilmStrip
v-if="item.isOfType(MediaSourceType.Special)"
weight="bold"
:aria-label="$t('media.attrs.timeline')"
/>
<PhSparkle
v-if="item.isOfType(MediaSourceType.Special)"
weight="bold"
:aria-label="$t('media.attrs.special')"
/>
</div>
</div>
<div class="flex items-center gap-1 px-1">
<p
v-tooltip.bottom="{ value: item.name.value, showDelay: 500 }"
v-tooltip.bottom="{ value: item.name, showDelay: 500 }"
class="line-clamp-2 flex-1 text-base"
>
{{ item.name.value }}
{{ item.name }}
</p>
<Button
v-if="size >= 96"
Expand Down Expand Up @@ -120,15 +129,16 @@
import { CurrentProject } from '@/stores/currentProject';
import {
PhDotsThreeVertical,
PhFilmStrip,
PhImage,
PhSparkle,
PhSpeakerHigh,
PhSubtitles,
PhTrash,
PhVideoCamera
} from '@phosphor-icons/vue';
import { ProjectFeatures } from '@safelight/shared/base/Project';
import type Media from '@safelight/shared/Media/Media';
import { MediaType } from '@safelight/shared/Media/Media';
import { MediaSourceType, type MediaItem } from '@safelight/shared/Media/Media';
import Button from 'primevue/button';
import Menu from 'primevue/menu';
import type { MenuItem } from 'primevue/menuitem';
Expand All @@ -138,7 +148,7 @@ import Toolbar from 'primevue/toolbar';
import { computed, ref } from 'vue';

const props = defineProps<{
item: Media;
item: MediaItem;
size: number;
}>();

Expand All @@ -148,6 +158,8 @@ const menuItems = ref<MenuItem[]>([
}
]);

const itemSourceType = computed(() => props.item.getMetadata('media')?.sourceType ?? 0);

const hasItemInTimeline = computed(
() =>
CurrentProject.project.value &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Panel
class="notification"
role="dialog"
:aria-label="notif.config.title"
:aria-describedby="notif.config.text"
:aria-label="$t(notif.config.title ?? '', 'notification.defaultTitle')"
:aria-describedby="'content-' + notif.id"
:aria-live="notif.config.severity == 'error' ? 'assertive' : 'polite'"
>
<template #header>
Expand All @@ -15,14 +15,14 @@
/>
<PhWarning v-if="notif.config.severity == 'warning'" />
</template>
<h3>{{ notif.config.title }}</h3>
<h3>{{ $t(notif.config.title ?? '', 'notification.defaultTitle') }}</h3>
<Button text severity="secondary" rounded @click="closeNotif">
<template #icon>
<PhX />
</template>
</Button>
</template>
<p class="mb-0">{{ notif.config.text }}</p>
<p class="mb-0" :id="'content-' + notif.id">{{ $t(notif.config.text ?? '') }}</p>
<div v-if="buttons.length > 0" class="align-items-center mt-4 flex gap-2">
<template v-for="(btn, i) in buttons" :key="i">
<Button
Expand All @@ -35,7 +35,7 @@
}
"
>
{{ btn.label }}
{{ $t(btn.label ?? '') }}
</Button>
</template>
</div>
Expand Down
Loading