includio-cms 0.1.3 → 0.5.0
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/CHANGELOG.md +76 -0
- package/ROADMAP.md +23 -13
- package/dist/admin/api/accept-invite.js +1 -5
- package/dist/admin/api/invite.js +7 -16
- package/dist/admin/client/account/account-page.svelte +20 -50
- package/dist/admin/client/account/lang.d.ts +15 -23
- package/dist/admin/client/account/lang.js +51 -67
- package/dist/admin/client/account/preferences-section.svelte +26 -84
- package/dist/admin/client/account/profile-section.svelte +60 -40
- package/dist/admin/client/account/schema.d.ts +11 -3
- package/dist/admin/client/account/schema.js +25 -16
- package/dist/admin/client/account/security-section.svelte +139 -105
- package/dist/admin/client/account/sessions-section.svelte +35 -34
- package/dist/admin/client/admin/admin-after-login-layout-content.svelte +3 -5
- package/dist/admin/client/admin/admin-layout.svelte +3 -2
- package/dist/admin/client/admin/admin-preloader.svelte +36 -0
- package/dist/admin/client/admin/admin-preloader.svelte.d.ts +18 -0
- package/dist/admin/client/admin/dashboard-page.svelte +55 -41
- package/dist/admin/client/collection/a11y-score-cell.svelte +45 -0
- package/dist/admin/client/collection/a11y-score-cell.svelte.d.ts +6 -0
- package/dist/admin/client/collection/bulk-actions-bar.svelte +83 -0
- package/dist/admin/client/collection/bulk-actions-bar.svelte.d.ts +9 -0
- package/dist/admin/client/collection/collection-entries.svelte +255 -256
- package/dist/admin/client/collection/collection-view.svelte.d.ts +4 -3
- package/dist/admin/client/collection/collection-view.svelte.js +9 -5
- package/dist/admin/client/collection/collection.svelte +22 -12
- package/dist/admin/client/collection/data-table.svelte +50 -39
- package/dist/admin/client/collection/data-table.svelte.d.ts +1 -0
- package/dist/admin/client/collection/date-cell.svelte +7 -5
- package/dist/admin/client/collection/date-cell.svelte.d.ts +1 -1
- package/dist/admin/client/collection/empty-state.svelte +28 -0
- package/dist/admin/client/collection/empty-state.svelte.d.ts +9 -0
- package/dist/admin/client/collection/entry-link.svelte +10 -4
- package/dist/admin/client/collection/entry-link.svelte.d.ts +1 -0
- package/dist/admin/client/collection/grid-view.svelte +21 -23
- package/dist/admin/client/collection/grid-view.svelte.d.ts +1 -2
- package/dist/admin/client/collection/row-actions.svelte +60 -0
- package/dist/admin/client/collection/row-actions.svelte.d.ts +9 -0
- package/dist/admin/client/collection/status-badge.svelte +7 -8
- package/dist/admin/client/collection/table-pagination.svelte +122 -79
- package/dist/admin/client/collection/table-pagination.svelte.d.ts +1 -0
- package/dist/admin/client/collection/table-toolbar.svelte +108 -88
- package/dist/admin/client/collection/table-toolbar.svelte.d.ts +8 -9
- package/dist/admin/client/entry/entry-form.svelte +109 -1
- package/dist/admin/client/entry/entry-header.svelte +96 -37
- package/dist/admin/client/entry/entry-header.svelte.d.ts +5 -0
- package/dist/admin/client/entry/entry.svelte +171 -60
- package/dist/admin/client/entry/header/a11y-validator.d.ts +46 -0
- package/dist/admin/client/entry/header/a11y-validator.js +311 -0
- package/dist/admin/client/entry/header/publish-panel.svelte +373 -131
- package/dist/admin/client/entry/header/publish-panel.svelte.d.ts +4 -0
- package/dist/admin/client/entry/header/save-indicator.svelte +33 -23
- package/dist/admin/client/entry/header/schedule-popover.svelte +1 -1
- package/dist/admin/client/entry/header/status-badge.svelte +25 -118
- package/dist/admin/client/entry/header/version-history-sheet.svelte +314 -98
- package/dist/admin/client/form/form-submission/form-submission.svelte +271 -83
- package/dist/admin/client/form/form-submission/submission-field.svelte +12 -12
- package/dist/admin/client/form/form-submissions.svelte +421 -139
- package/dist/admin/client/form/submission-link.svelte +8 -2
- package/dist/admin/client/form/submission-link.svelte.d.ts +1 -0
- package/dist/admin/client/form/submission-status-badge.svelte +18 -4
- package/dist/admin/client/form/submission-status-badge.svelte.d.ts +1 -0
- package/dist/admin/client/login/lang.d.ts +32 -0
- package/dist/admin/client/login/lang.js +66 -2
- package/dist/admin/client/login/login-form.svelte +237 -95
- package/dist/admin/client/login/login-form.svelte.d.ts +2 -17
- package/dist/admin/client/login/login-page.svelte +34 -98
- package/dist/admin/client/login/reset-password-page.svelte +235 -0
- package/dist/admin/client/login/reset-password-page.svelte.d.ts +4 -0
- package/dist/admin/client/login/schema.d.ts +15 -0
- package/dist/admin/client/login/schema.js +21 -0
- package/dist/admin/client/users/accept-invite-page.svelte +166 -37
- package/dist/admin/client/users/create-user-dialog.svelte +15 -7
- package/dist/admin/client/users/delete-user-dialog.svelte +81 -16
- package/dist/admin/client/users/delete-user-dialog.svelte.d.ts +4 -1
- package/dist/admin/client/users/edit-user-dialog.svelte +3 -0
- package/dist/admin/client/users/invite-user-dialog.svelte +16 -3
- package/dist/admin/client/users/lang.d.ts +27 -0
- package/dist/admin/client/users/lang.js +64 -10
- package/dist/admin/client/users/pending-invitations.svelte +59 -23
- package/dist/admin/client/users/users-page.svelte +471 -72
- package/dist/admin/components/accessibility/accessibility-overview.svelte +2 -7
- package/dist/admin/components/dashboard/a11y-gauge.svelte +90 -0
- package/dist/admin/components/dashboard/a11y-gauge.svelte.d.ts +18 -0
- package/dist/admin/components/dashboard/accessibility-hub.svelte +13 -12
- package/dist/admin/components/dashboard/form-submissions-widget.svelte +71 -113
- package/dist/admin/components/dashboard/index.d.ts +4 -2
- package/dist/admin/components/dashboard/index.js +4 -2
- package/dist/admin/components/dashboard/recent-activity.svelte +53 -75
- package/dist/admin/components/dashboard/recent-entries.svelte +94 -0
- package/dist/admin/components/dashboard/recent-entries.svelte.d.ts +18 -0
- package/dist/admin/components/dashboard/stat-card.svelte +2 -2
- package/dist/admin/components/dashboard/tip-of-the-day.svelte +109 -0
- package/dist/admin/components/dashboard/tip-of-the-day.svelte.d.ts +3 -0
- package/dist/admin/components/dashboard/welcome-header.svelte +45 -0
- package/dist/admin/components/dashboard/welcome-header.svelte.d.ts +3 -0
- package/dist/admin/components/fields/{array-field.svelte → blocks-field.svelte} +4 -4
- package/dist/admin/components/fields/{array-field.svelte.d.ts → blocks-field.svelte.d.ts} +5 -5
- package/dist/admin/components/fields/content-field.svelte +27 -0
- package/dist/admin/components/fields/content-field.svelte.d.ts +31 -0
- package/dist/admin/components/fields/field-renderer.svelte +9 -7
- package/dist/admin/components/fields/image-field.svelte +2 -2
- package/dist/admin/components/fields/media-field.svelte +2 -2
- package/dist/admin/components/fields/seo-field.svelte +205 -25
- package/dist/admin/components/fields/simple-array-field.svelte +289 -0
- package/dist/admin/components/fields/simple-array-field.svelte.d.ts +30 -0
- package/dist/admin/components/fields/slug-field.svelte +3 -2
- package/dist/admin/components/fields/standalone-field-renderer.svelte +148 -0
- package/dist/admin/components/fields/standalone-field-renderer.svelte.d.ts +9 -0
- package/dist/admin/components/fields/text-field-wrapper.svelte +13 -1
- package/dist/admin/components/fields/text-field-wrapper.svelte.d.ts +2 -2
- package/dist/admin/components/fields/url-field.svelte +5 -4
- package/dist/admin/components/layout/app-sidebar.svelte +27 -24
- package/dist/admin/components/layout/lang.d.ts +6 -0
- package/dist/admin/components/layout/lang.js +13 -1
- package/dist/admin/components/layout/layout-renderer.svelte +352 -0
- package/dist/admin/components/layout/layout-renderer.svelte.d.ts +14 -0
- package/dist/admin/components/layout/nav-breadcrumbs.svelte +4 -4
- package/dist/admin/components/layout/nav-collections.svelte +65 -36
- package/dist/admin/components/layout/nav-footer.svelte +31 -0
- package/dist/admin/components/layout/nav-footer.svelte.d.ts +18 -0
- package/dist/admin/components/layout/nav-forms.svelte +55 -30
- package/dist/admin/components/layout/nav-main.svelte +14 -52
- package/dist/admin/components/layout/nav-search.svelte +4 -3
- package/dist/admin/components/layout/nav-singletons.svelte +59 -17
- package/dist/admin/components/layout/nav-singletons.svelte.d.ts +17 -8
- package/dist/admin/components/layout/site-header.svelte +74 -13
- package/dist/admin/components/media/alt-input.svelte +32 -22
- package/dist/admin/components/media/bulk-action-bar.svelte +139 -150
- package/dist/admin/components/media/file/file-details.svelte +299 -217
- package/dist/admin/components/media/file/file-miniature.svelte +54 -41
- package/dist/admin/components/media/file/file-miniature.svelte.d.ts +1 -0
- package/dist/admin/components/media/file/file-preview.svelte +1 -1
- package/dist/admin/components/media/file-upload.svelte +24 -26
- package/dist/admin/components/media/files-list.svelte +112 -40
- package/dist/admin/components/media/files-list.svelte.d.ts +2 -0
- package/dist/admin/components/media/focal-point-input.svelte +122 -26
- package/dist/admin/components/media/media-library.svelte +127 -70
- package/dist/admin/components/media/media-search.svelte +6 -6
- package/dist/admin/components/media/media-sort.svelte +3 -1
- package/dist/admin/components/media/multi-file-summary.svelte +88 -68
- package/dist/admin/components/media/tag-combobox.svelte +141 -66
- package/dist/admin/components/media/tag-combobox.svelte.d.ts +1 -0
- package/dist/admin/components/media/tag-sidebar.svelte +139 -121
- package/dist/admin/components/tiptap/FigureNodeView.svelte +144 -15
- package/dist/admin/components/tiptap/InlineBlockNodeView.svelte +254 -0
- package/dist/admin/components/tiptap/InlineBlockNodeView.svelte.d.ts +4 -0
- package/dist/admin/components/tiptap/SlashCommandPopup.svelte +212 -0
- package/dist/admin/components/tiptap/SlashCommandPopup.svelte.d.ts +8 -0
- package/dist/admin/components/tiptap/content-editor.svelte +280 -0
- package/dist/admin/components/tiptap/content-editor.svelte.d.ts +9 -0
- package/dist/admin/components/tiptap/editor-toolbar.svelte +230 -0
- package/dist/admin/components/tiptap/editor-toolbar.svelte.d.ts +16 -0
- package/dist/admin/components/tiptap/heading-a11y-plugin.d.ts +2 -0
- package/dist/admin/components/tiptap/heading-a11y-plugin.js +67 -0
- package/dist/admin/components/tiptap/image-dialog.svelte +172 -11
- package/dist/admin/components/tiptap/inline-block-node.d.ts +19 -0
- package/dist/admin/components/tiptap/inline-block-node.js +98 -0
- package/dist/admin/components/tiptap/link-dialog.svelte +9 -4
- package/dist/admin/components/tiptap/slash-command.d.ts +17 -0
- package/dist/admin/components/tiptap/slash-command.js +181 -0
- package/dist/admin/components/tiptap/structured-content-utils.d.ts +21 -0
- package/dist/admin/components/tiptap/structured-content-utils.js +150 -0
- package/dist/admin/components/tiptap/tiptap-editor.svelte +18 -190
- package/dist/admin/email/invite-template.d.ts +8 -0
- package/dist/admin/email/invite-template.js +99 -0
- package/dist/admin/email/reset-password-template.d.ts +7 -0
- package/dist/admin/email/reset-password-template.js +96 -0
- package/dist/admin/remote/ai.remote.d.ts +1 -0
- package/dist/admin/remote/ai.remote.js +4 -1
- package/dist/admin/remote/entry.remote.d.ts +8 -0
- package/dist/admin/remote/entry.remote.js +53 -4
- package/dist/admin/remote/preview.remote.js +2 -1
- package/dist/admin/shared/password-schema.d.ts +5 -0
- package/dist/admin/shared/password-schema.js +10 -0
- package/dist/admin/styles/admin.css +1530 -151
- package/dist/admin/utils/formatDate.d.ts +1 -0
- package/dist/admin/utils/formatDate.js +8 -0
- package/dist/admin/utils/roleLabel.d.ts +2 -0
- package/dist/admin/utils/roleLabel.js +13 -0
- package/dist/ai-claude/index.d.ts +2 -0
- package/dist/ai-claude/index.js +56 -0
- package/dist/cms/runtime/api.d.ts +6 -1
- package/dist/cms/runtime/api.js +3 -0
- package/dist/cms/runtime/schemas.d.ts +9 -1
- package/dist/cms/runtime/schemas.js +8 -0
- package/dist/cms/runtime/types.d.ts +82 -10
- package/dist/cms/runtime/types.js +4 -0
- package/dist/components/ui/accordion/accordion.stories.svelte +39 -0
- package/dist/components/ui/accordion/accordion.stories.svelte.d.ts +27 -0
- package/dist/components/ui/alert/alert.stories.svelte +53 -0
- package/dist/components/ui/alert/alert.stories.svelte.d.ts +27 -0
- package/dist/components/ui/alert/alert.svelte +5 -0
- package/dist/components/ui/alert/alert.svelte.d.ts +9 -0
- package/dist/components/ui/avatar/avatar.stories.svelte +16 -0
- package/dist/components/ui/avatar/avatar.stories.svelte.d.ts +27 -0
- package/dist/components/ui/badge/badge.stories.svelte +33 -0
- package/dist/components/ui/badge/badge.stories.svelte.d.ts +27 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte +33 -0
- package/dist/components/ui/breadcrumb/breadcrumb.stories.svelte.d.ts +27 -0
- package/dist/components/ui/button/button.stories.svelte +43 -0
- package/dist/components/ui/button/button.stories.svelte.d.ts +27 -0
- package/dist/components/ui/button/button.svelte +1 -2
- package/dist/components/ui/button/button.svelte.d.ts +0 -3
- package/dist/components/ui/button-group/button-group-separator.svelte.d.ts +1 -1
- package/dist/components/ui/card/card.stories.svelte +42 -0
- package/dist/components/ui/card/card.stories.svelte.d.ts +27 -0
- package/dist/components/ui/command/command.stories.svelte +51 -0
- package/dist/components/ui/command/command.stories.svelte.d.ts +27 -0
- package/dist/components/ui/dialog/dialog.stories.svelte +29 -0
- package/dist/components/ui/dialog/dialog.stories.svelte.d.ts +27 -0
- package/dist/components/ui/field/field-label.svelte.d.ts +1 -1
- package/dist/components/ui/field/field.stories.svelte +21 -0
- package/dist/components/ui/field/field.stories.svelte.d.ts +27 -0
- package/dist/components/ui/input/input.stories.svelte +40 -0
- package/dist/components/ui/input/input.stories.svelte.d.ts +27 -0
- package/dist/components/ui/input/input.svelte +2 -4
- package/dist/components/ui/item/item-separator.svelte.d.ts +1 -1
- package/dist/components/ui/label/label.stories.svelte +20 -0
- package/dist/components/ui/label/label.stories.svelte.d.ts +27 -0
- package/dist/components/ui/popover/popover.stories.svelte +29 -0
- package/dist/components/ui/popover/popover.stories.svelte.d.ts +27 -0
- package/dist/components/ui/select/select-group-heading.svelte.d.ts +1 -1
- package/dist/components/ui/select/select.stories.svelte +23 -0
- package/dist/components/ui/select/select.stories.svelte.d.ts +27 -0
- package/dist/components/ui/separator/separator.stories.svelte +24 -0
- package/dist/components/ui/separator/separator.stories.svelte.d.ts +27 -0
- package/dist/components/ui/sheet/sheet.stories.svelte +29 -0
- package/dist/components/ui/sheet/sheet.stories.svelte.d.ts +27 -0
- package/dist/components/ui/sidebar/sidebar-group.svelte +3 -3
- package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +2 -2
- package/dist/components/ui/sidebar/sidebar-menu-button.svelte +28 -30
- package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +7 -7
- package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +1 -1
- package/dist/components/ui/sidebar/sidebar-trigger.svelte +4 -4
- package/dist/components/ui/sonner/sonner.stories.svelte +22 -0
- package/dist/components/ui/sonner/sonner.stories.svelte.d.ts +26 -0
- package/dist/components/ui/sonner/sonner.svelte +8 -2
- package/dist/components/ui/sonner/toast-demo.svelte +29 -0
- package/dist/components/ui/sonner/toast-demo.svelte.d.ts +6 -0
- package/dist/components/ui/textarea/textarea.stories.svelte +22 -0
- package/dist/components/ui/textarea/textarea.stories.svelte.d.ts +27 -0
- package/dist/components/ui/textarea/textarea.svelte +0 -2
- package/dist/components/ui/toggle/toggle.stories.svelte +22 -0
- package/dist/components/ui/toggle/toggle.stories.svelte.d.ts +27 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.svelte +17 -0
- package/dist/components/ui/toggle-group/toggle-group.stories.svelte.d.ts +27 -0
- package/dist/components/ui/tooltip/tooltip.stories.svelte +26 -0
- package/dist/components/ui/tooltip/tooltip.stories.svelte.d.ts +27 -0
- package/dist/core/fields/fieldSchemaToTs.d.ts +1 -0
- package/dist/core/fields/fieldSchemaToTs.js +133 -1
- package/dist/core/fields/layoutUtils.d.ts +17 -0
- package/dist/core/fields/layoutUtils.js +149 -0
- package/dist/core/fields/structuredToHtml.d.ts +9 -0
- package/dist/core/fields/structuredToHtml.js +161 -0
- package/dist/core/server/entries/operations/create.js +2 -1
- package/dist/core/server/entries/operations/get.js +8 -6
- package/dist/core/server/entries/operations/update.d.ts +3 -0
- package/dist/core/server/entries/operations/update.js +30 -2
- package/dist/core/server/fields/queryStructuredContent.d.ts +15 -0
- package/dist/core/server/fields/queryStructuredContent.js +65 -0
- package/dist/core/server/fields/resolveImageFields.js +51 -2
- package/dist/core/server/fields/resolveRelationFields.js +2 -2
- package/dist/core/server/fields/resolveRichtextLinks.js +80 -13
- package/dist/core/server/fields/resolveUrlFields.js +57 -6
- package/dist/core/server/fields/slugResolver.d.ts +10 -0
- package/dist/core/server/fields/slugResolver.js +34 -0
- package/dist/core/server/generator/fields.js +15 -4
- package/dist/core/server/generator/generator.js +3 -2
- package/dist/files-local/index.js +126 -64
- package/dist/paraglide/.prettierignore +3 -0
- package/dist/paraglide/messages/_index.d.ts +36 -0
- package/dist/paraglide/messages/_index.js +72 -0
- package/dist/paraglide/messages/en.d.ts +5 -0
- package/dist/paraglide/messages/en.js +14 -0
- package/dist/paraglide/messages/pl.d.ts +5 -0
- package/dist/paraglide/messages/pl.js +14 -0
- package/dist/paraglide/messages.d.ts +2 -0
- package/dist/paraglide/messages.js +4 -0
- package/dist/paraglide/registry.d.ts +21 -0
- package/dist/paraglide/registry.js +31 -0
- package/dist/paraglide/runtime.d.ts +583 -0
- package/dist/paraglide/runtime.js +1402 -0
- package/dist/paraglide/server.d.ts +67 -0
- package/dist/paraglide/server.js +175 -0
- package/dist/server/auth.d.ts +5 -0
- package/dist/server/auth.js +12 -1
- package/dist/sveltekit/components/structured-content.svelte +204 -0
- package/dist/sveltekit/components/structured-content.svelte.d.ts +21 -0
- package/dist/sveltekit/config.d.ts +13 -3
- package/dist/sveltekit/index.d.ts +3 -0
- package/dist/sveltekit/index.js +3 -0
- package/dist/sveltekit/server/handle.js +1 -0
- package/dist/types/config.d.ts +3 -0
- package/dist/types/fields.d.ts +19 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/layout.d.ts +54 -0
- package/dist/types/layout.js +6 -0
- package/dist/types/structured-content.d.ts +63 -0
- package/dist/types/structured-content.js +1 -0
- package/dist/updates/0.1.4/index.d.ts +2 -0
- package/dist/updates/0.1.4/index.js +11 -0
- package/dist/updates/0.1.5/index.d.ts +2 -0
- package/dist/updates/0.1.5/index.js +18 -0
- package/dist/updates/0.2.0/index.d.ts +2 -0
- package/dist/updates/0.2.0/index.js +11 -0
- package/dist/updates/0.2.2/index.d.ts +2 -0
- package/dist/updates/0.2.2/index.js +13 -0
- package/dist/updates/0.5.0/index.d.ts +2 -0
- package/dist/updates/0.5.0/index.js +14 -0
- package/dist/updates/index.js +6 -1
- package/package.json +17 -10
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { useInterfaceLanguage } from '../../../state/interface-language.svelte.js';
|
|
3
3
|
import Button from '../../../../components/ui/button/button.svelte';
|
|
4
|
-
import Label from '../../../../components/ui/label/label.svelte';
|
|
5
4
|
import { getRemotes } from '../../../../sveltekit/index.js';
|
|
6
5
|
import type { InterfaceLanguage } from '../../../../types/languages.js';
|
|
7
6
|
import type { MediaFile, MediaTag } from '../../../../types/media.js';
|
|
@@ -10,38 +9,47 @@
|
|
|
10
9
|
import TagCombobox from '../tag-combobox.svelte';
|
|
11
10
|
import FileMiniature from './file-miniature.svelte';
|
|
12
11
|
import MediaSelector from '../media-selector.svelte';
|
|
13
|
-
import * as InputGroup from '../../../../components/ui/input-group/index.js';
|
|
14
12
|
import * as Dialog from '../../../../components/ui/dialog/index.js';
|
|
13
|
+
import * as AlertDialog from '../../../../components/ui/alert-dialog/index.js';
|
|
15
14
|
import Check from '@tabler/icons-svelte/icons/check';
|
|
16
15
|
import Copy from '@tabler/icons-svelte/icons/copy';
|
|
17
|
-
import Upload from '@tabler/icons-svelte/icons/upload';
|
|
18
16
|
import Replace from '@tabler/icons-svelte/icons/replace';
|
|
19
17
|
import CircleCheck from '@tabler/icons-svelte/icons/circle-check';
|
|
20
18
|
import AlertTriangle from '@tabler/icons-svelte/icons/alert-triangle';
|
|
19
|
+
import Music from '@tabler/icons-svelte/icons/music';
|
|
20
|
+
import Upload from '@tabler/icons-svelte/icons/upload';
|
|
21
|
+
import Trash from '@tabler/icons-svelte/icons/trash';
|
|
22
|
+
import VideoOff from '@tabler/icons-svelte/icons/video-off';
|
|
23
|
+
import Download from '@tabler/icons-svelte/icons/download';
|
|
21
24
|
import { UseClipboard } from '../../../../components/hooks/use-clipboard.svelte.js';
|
|
22
25
|
import { page } from '$app/state';
|
|
23
26
|
import FileNameInput from './file-name-input.svelte';
|
|
24
27
|
|
|
25
28
|
let lightboxOpen = $state(false);
|
|
29
|
+
let deleteDialogOpen = $state(false);
|
|
30
|
+
let videoError = $state(false);
|
|
31
|
+
|
|
32
|
+
$effect(() => {
|
|
33
|
+
file.url;
|
|
34
|
+
videoError = false;
|
|
35
|
+
});
|
|
26
36
|
|
|
27
37
|
const lang: Record<
|
|
28
38
|
InterfaceLanguage,
|
|
29
39
|
{
|
|
30
|
-
fileDeletedToast: string;
|
|
31
|
-
allTabs: string;
|
|
32
40
|
fileDeleteLabel: string;
|
|
41
|
+
deleteConfirmTitle: string;
|
|
42
|
+
deleteConfirmDesc: string;
|
|
43
|
+
deleteCancel: string;
|
|
33
44
|
fileNameLabel: string;
|
|
34
45
|
fileUrlLabel: string;
|
|
35
46
|
fileAltLabel: string;
|
|
36
|
-
|
|
47
|
+
fileAltHint: string;
|
|
37
48
|
createdAtLabel: string;
|
|
38
49
|
mimeTypeLabel: string;
|
|
39
50
|
sizeLabel: string;
|
|
40
51
|
dimensionsLabel: string;
|
|
41
|
-
selectedInfo: string;
|
|
42
|
-
selectionResetLabel: string;
|
|
43
52
|
durationLabel: string;
|
|
44
|
-
minutes: string;
|
|
45
53
|
transcriptLabel: string;
|
|
46
54
|
audioDescriptionLabel: string;
|
|
47
55
|
posterLabel: string;
|
|
@@ -51,25 +59,28 @@
|
|
|
51
59
|
changePoster: string;
|
|
52
60
|
removeFile: string;
|
|
53
61
|
replaceFileLabel: string;
|
|
62
|
+
tagsLabel: string;
|
|
63
|
+
metadataLabel: string;
|
|
64
|
+
focalPointLabel: string;
|
|
65
|
+
videoUnsupported: string;
|
|
66
|
+
downloadFile: string;
|
|
54
67
|
}
|
|
55
68
|
> = {
|
|
56
69
|
pl: {
|
|
57
|
-
fileDeleteLabel: 'Usuń
|
|
70
|
+
fileDeleteLabel: 'Usuń',
|
|
71
|
+
deleteConfirmTitle: 'Usunąć plik?',
|
|
72
|
+
deleteConfirmDesc: 'Plik zostanie trwale usunięty.',
|
|
73
|
+
deleteCancel: 'Anuluj',
|
|
58
74
|
replaceFileLabel: 'Zamień plik',
|
|
59
|
-
fileNameLabel: 'Nazwa',
|
|
75
|
+
fileNameLabel: 'Nazwa pliku',
|
|
60
76
|
fileUrlLabel: 'URL',
|
|
61
77
|
fileAltLabel: 'Tekst alternatywny',
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
mimeTypeLabel: 'Typ MIME:',
|
|
69
|
-
sizeLabel: 'Rozmiar:',
|
|
70
|
-
dimensionsLabel: 'Wymiary:',
|
|
71
|
-
durationLabel: 'Czas trwania:',
|
|
72
|
-
minutes: 'minuty',
|
|
78
|
+
fileAltHint: 'Dodaj opis, żeby każdy mógł zrozumieć treść obrazu',
|
|
79
|
+
createdAtLabel: 'Utworzono',
|
|
80
|
+
mimeTypeLabel: 'Typ',
|
|
81
|
+
sizeLabel: 'Rozmiar',
|
|
82
|
+
dimensionsLabel: 'Wymiary',
|
|
83
|
+
durationLabel: 'Czas',
|
|
73
84
|
transcriptLabel: 'Transkrypcja',
|
|
74
85
|
audioDescriptionLabel: 'Audiodeskrypcja',
|
|
75
86
|
posterLabel: 'Poster',
|
|
@@ -77,24 +88,27 @@
|
|
|
77
88
|
uploadTranscript: 'Dodaj transkrypcję',
|
|
78
89
|
uploadAudioDescription: 'Dodaj audiodeskrypcję',
|
|
79
90
|
changePoster: 'Zmień poster',
|
|
80
|
-
removeFile: 'Usuń'
|
|
91
|
+
removeFile: 'Usuń',
|
|
92
|
+
tagsLabel: 'Tagi',
|
|
93
|
+
metadataLabel: 'Metadane',
|
|
94
|
+
focalPointLabel: 'Punkt ogniskowy',
|
|
95
|
+
videoUnsupported: 'Ten format wideo nie jest obsługiwany w przeglądarce',
|
|
96
|
+
downloadFile: 'Pobierz'
|
|
81
97
|
},
|
|
82
98
|
en: {
|
|
83
|
-
fileDeleteLabel: 'Delete
|
|
84
|
-
|
|
99
|
+
fileDeleteLabel: 'Delete',
|
|
100
|
+
deleteConfirmTitle: 'Delete file?',
|
|
101
|
+
deleteConfirmDesc: 'The file will be permanently deleted.',
|
|
102
|
+
deleteCancel: 'Cancel',
|
|
103
|
+
fileNameLabel: 'File name',
|
|
85
104
|
fileUrlLabel: 'URL',
|
|
86
105
|
fileAltLabel: 'Alt text',
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
mimeTypeLabel: 'MIME type:',
|
|
94
|
-
sizeLabel: 'Size:',
|
|
95
|
-
dimensionsLabel: 'Dimensions:',
|
|
96
|
-
durationLabel: 'Duration:',
|
|
97
|
-
minutes: 'minutes',
|
|
106
|
+
fileAltHint: 'Add a description so everyone can understand the image',
|
|
107
|
+
createdAtLabel: 'Created',
|
|
108
|
+
mimeTypeLabel: 'Type',
|
|
109
|
+
sizeLabel: 'Size',
|
|
110
|
+
dimensionsLabel: 'Dimensions',
|
|
111
|
+
durationLabel: 'Duration',
|
|
98
112
|
transcriptLabel: 'Transcript',
|
|
99
113
|
audioDescriptionLabel: 'Audio description',
|
|
100
114
|
posterLabel: 'Poster',
|
|
@@ -103,7 +117,12 @@
|
|
|
103
117
|
uploadAudioDescription: 'Add audio description',
|
|
104
118
|
changePoster: 'Change poster',
|
|
105
119
|
removeFile: 'Remove',
|
|
106
|
-
replaceFileLabel: 'Replace file'
|
|
120
|
+
replaceFileLabel: 'Replace file',
|
|
121
|
+
tagsLabel: 'Tags',
|
|
122
|
+
metadataLabel: 'Metadata',
|
|
123
|
+
focalPointLabel: 'Focal point',
|
|
124
|
+
videoUnsupported: 'This video format is not supported in the browser',
|
|
125
|
+
downloadFile: 'Download'
|
|
107
126
|
}
|
|
108
127
|
};
|
|
109
128
|
|
|
@@ -126,9 +145,7 @@
|
|
|
126
145
|
onDelete: () => void;
|
|
127
146
|
onReplace: (updated: MediaFile) => void;
|
|
128
147
|
onNameUpdate: (newName: string) => Promise<
|
|
129
|
-
| {
|
|
130
|
-
success: true;
|
|
131
|
-
}
|
|
148
|
+
| { success: true }
|
|
132
149
|
| { success: false; error: 'name-already-exists' }
|
|
133
150
|
>;
|
|
134
151
|
onTagUpdate: (tagIds: string[]) => void;
|
|
@@ -163,7 +180,6 @@
|
|
|
163
180
|
|
|
164
181
|
let fileUrl = $derived(file.url.startsWith('/') ? page.url.origin + file.url : file.url);
|
|
165
182
|
|
|
166
|
-
// Accessibility state for video files
|
|
167
183
|
let transcriptDialogOpen = $state(false);
|
|
168
184
|
let audioDescDialogOpen = $state(false);
|
|
169
185
|
let posterDialogOpen = $state(false);
|
|
@@ -172,7 +188,7 @@
|
|
|
172
188
|
let posterSelected = $state<string>('');
|
|
173
189
|
|
|
174
190
|
$effect(() => {
|
|
175
|
-
if (transcriptSelected && file.type === 'video') {
|
|
191
|
+
if (transcriptSelected && (file.type === 'video' || file.type === 'audio')) {
|
|
176
192
|
remotes.updateMediaAccessibility({
|
|
177
193
|
fileId: file.id,
|
|
178
194
|
transcriptFileId: transcriptSelected
|
|
@@ -184,7 +200,7 @@
|
|
|
184
200
|
});
|
|
185
201
|
|
|
186
202
|
$effect(() => {
|
|
187
|
-
if (audioDescSelected && file.type === 'video') {
|
|
203
|
+
if (audioDescSelected && (file.type === 'video' || file.type === 'audio')) {
|
|
188
204
|
remotes.updateMediaAccessibility({
|
|
189
205
|
fileId: file.id,
|
|
190
206
|
audioDescriptionFileId: audioDescSelected
|
|
@@ -212,192 +228,270 @@
|
|
|
212
228
|
});
|
|
213
229
|
</script>
|
|
214
230
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
<
|
|
218
|
-
|
|
219
|
-
<
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
<Button type="button" size="sm" variant="destructive" onclick={onDelete}>
|
|
223
|
-
{lang[interfaceLanguage.current].fileDeleteLabel}
|
|
224
|
-
</Button>
|
|
225
|
-
</div>
|
|
226
|
-
|
|
227
|
-
<!-- Główna zawartość -->
|
|
228
|
-
<div class="space-y-5 p-5">
|
|
229
|
-
<!-- Preview -->
|
|
230
|
-
<div>
|
|
231
|
-
{#if file.type === 'video'}
|
|
232
|
-
<div class="w-full overflow-hidden rounded-xl shadow-md">
|
|
233
|
-
<video controls poster={file.posterUrl || file.thumbnailUrl || undefined} class="w-full max-h-48 object-contain bg-black rounded-xl">
|
|
234
|
-
<source src={file.url} type={file.mimeType || undefined} />
|
|
235
|
-
</video>
|
|
236
|
-
</div>
|
|
237
|
-
{:else}
|
|
231
|
+
<div class="flex h-full flex-col overflow-hidden">
|
|
232
|
+
<!-- Scrollable content -->
|
|
233
|
+
<div class="flex-1 overflow-y-auto p-5 scrollbar-thin space-y-4">
|
|
234
|
+
<!-- Header: title + action buttons -->
|
|
235
|
+
<div class="flex items-center gap-2 flex-wrap">
|
|
236
|
+
<h2 class="flex-1 min-w-0 truncate text-base font-bold text-foreground">{file.name}</h2>
|
|
237
|
+
<input type="file" class="hidden" bind:this={replaceInputEl} onchange={handleReplace} />
|
|
238
238
|
<button
|
|
239
239
|
type="button"
|
|
240
|
-
class="
|
|
241
|
-
|
|
240
|
+
class="inline-flex items-center gap-1 rounded-md border border-border px-2.5 py-1 text-xs font-medium text-muted-foreground transition-colors hover:bg-lavender-lighter hover:border-lavender hover:text-primary"
|
|
241
|
+
disabled={replacing}
|
|
242
|
+
onclick={() => replaceInputEl.click()}
|
|
242
243
|
>
|
|
243
|
-
<
|
|
244
|
+
<Replace class="h-3.5 w-3.5" />
|
|
245
|
+
{lang[interfaceLanguage.current].replaceFileLabel}
|
|
244
246
|
</button>
|
|
245
|
-
|
|
246
|
-
|
|
247
|
+
<button
|
|
248
|
+
type="button"
|
|
249
|
+
class="inline-flex items-center gap-1 rounded-md border border-destructive/30 px-2.5 py-1 text-xs font-medium text-destructive transition-colors hover:bg-error-bg hover:border-destructive/50"
|
|
250
|
+
onclick={() => (deleteDialogOpen = true)}
|
|
251
|
+
>
|
|
252
|
+
<Trash class="h-3.5 w-3.5" />
|
|
253
|
+
{lang[interfaceLanguage.current].fileDeleteLabel}
|
|
254
|
+
</button>
|
|
255
|
+
</div>
|
|
247
256
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
257
|
+
<!-- Preview -->
|
|
258
|
+
<div>
|
|
259
|
+
{#if file.type === 'video'}
|
|
260
|
+
{#if videoError}
|
|
261
|
+
<div class="w-full aspect-video flex flex-col items-center justify-center gap-3 rounded-lg bg-muted">
|
|
262
|
+
<VideoOff class="h-12 w-12 text-text-light" />
|
|
263
|
+
<p class="text-sm text-muted-foreground text-center px-4">{lang[interfaceLanguage.current].videoUnsupported}</p>
|
|
264
|
+
<a
|
|
265
|
+
href={file.url}
|
|
266
|
+
download
|
|
267
|
+
class="inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground transition-colors hover:bg-primary/90"
|
|
268
|
+
>
|
|
269
|
+
<Download class="h-3.5 w-3.5" />
|
|
270
|
+
{lang[interfaceLanguage.current].downloadFile}
|
|
271
|
+
</a>
|
|
272
|
+
</div>
|
|
273
|
+
{:else}
|
|
274
|
+
<div class="w-full overflow-hidden rounded-lg shadow-sm">
|
|
275
|
+
<video
|
|
276
|
+
controls
|
|
277
|
+
poster={file.posterUrl || file.thumbnailUrl || undefined}
|
|
278
|
+
class="w-full aspect-video object-contain bg-black rounded-lg"
|
|
279
|
+
onerror={() => (videoError = true)}
|
|
280
|
+
>
|
|
281
|
+
<source src={file.url} />
|
|
282
|
+
</video>
|
|
283
|
+
</div>
|
|
284
|
+
{/if}
|
|
285
|
+
{:else if file.type === 'image'}
|
|
286
|
+
<button
|
|
287
|
+
type="button"
|
|
288
|
+
class="relative w-full aspect-video overflow-hidden rounded-lg ml-checkered-bg cursor-zoom-in hover:ring-2 hover:ring-primary/50 transition-all"
|
|
289
|
+
onclick={() => (lightboxOpen = true)}
|
|
269
290
|
>
|
|
270
|
-
{
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
291
|
+
<img src={file.url} alt={file.alt || file.name} class="w-full h-full object-contain" />
|
|
292
|
+
</button>
|
|
293
|
+
{:else if file.type === 'audio'}
|
|
294
|
+
<div class="w-full overflow-hidden rounded-lg">
|
|
295
|
+
<div class="flex flex-col items-center justify-center gap-3 bg-muted py-8 rounded-t-lg">
|
|
296
|
+
<Music class="h-12 w-12 text-text-light" />
|
|
297
|
+
</div>
|
|
298
|
+
<audio controls class="w-full rounded-b-lg">
|
|
299
|
+
<source src={file.url} />
|
|
300
|
+
</audio>
|
|
301
|
+
</div>
|
|
302
|
+
{:else}
|
|
303
|
+
<div class="relative w-full aspect-video overflow-hidden rounded-lg">
|
|
304
|
+
<FileMiniature {file} mode="thumb" />
|
|
305
|
+
</div>
|
|
306
|
+
{/if}
|
|
307
|
+
</div>
|
|
279
308
|
|
|
280
|
-
|
|
281
|
-
{#if file.type === 'image'}
|
|
309
|
+
<!-- Tags -->
|
|
282
310
|
<div class="space-y-1.5">
|
|
283
|
-
<
|
|
284
|
-
<
|
|
311
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].tagsLabel}</div>
|
|
312
|
+
<TagCombobox
|
|
313
|
+
tags={allTags}
|
|
314
|
+
selectedTagIds={file.tags.map((t) => t.id)}
|
|
315
|
+
onchange={onTagUpdate}
|
|
316
|
+
showLabel={false}
|
|
317
|
+
/>
|
|
285
318
|
</div>
|
|
286
|
-
<FocalPointInput {file} />
|
|
287
|
-
{/if}
|
|
288
|
-
|
|
289
|
-
<!-- Accessibility section for video -->
|
|
290
|
-
{#if file.type === 'video'}
|
|
291
|
-
<div class="space-y-3">
|
|
292
|
-
<Label class="text-xs font-semibold">{lang[interfaceLanguage.current].accessibilityLabel}</Label>
|
|
293
|
-
|
|
294
|
-
<!-- Transcript -->
|
|
295
|
-
<div class="flex items-center justify-between gap-2 rounded-lg border p-2">
|
|
296
|
-
<div class="flex items-center gap-2 text-xs">
|
|
297
|
-
{#if file.transcriptFileId}
|
|
298
|
-
<CircleCheck class="h-4 w-4 text-green-500" />
|
|
299
|
-
<span>{lang[interfaceLanguage.current].transcriptLabel}</span>
|
|
300
|
-
{:else}
|
|
301
|
-
<AlertTriangle class="h-4 w-4 text-yellow-500" />
|
|
302
|
-
<span class="text-muted-foreground">{lang[interfaceLanguage.current].transcriptLabel}</span>
|
|
303
|
-
{/if}
|
|
304
|
-
</div>
|
|
305
|
-
<div class="flex gap-1">
|
|
306
|
-
{#if file.transcriptFileId}
|
|
307
|
-
<Button size="sm" variant="ghost" class="h-6 text-xs" onclick={() => {
|
|
308
|
-
remotes.updateMediaAccessibility({ fileId: file.id, transcriptFileId: null });
|
|
309
|
-
file.transcriptFileId = null;
|
|
310
|
-
}}>
|
|
311
|
-
{lang[interfaceLanguage.current].removeFile}
|
|
312
|
-
</Button>
|
|
313
|
-
{/if}
|
|
314
|
-
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (transcriptDialogOpen = true)}>
|
|
315
|
-
<Upload class="h-3 w-3 mr-1" />
|
|
316
|
-
{lang[interfaceLanguage.current].uploadTranscript}
|
|
317
|
-
</Button>
|
|
318
|
-
</div>
|
|
319
|
-
</div>
|
|
320
319
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
<span>{lang[interfaceLanguage.current].audioDescriptionLabel}</span>
|
|
327
|
-
{:else}
|
|
328
|
-
<AlertTriangle class="h-4 w-4 text-yellow-500" />
|
|
329
|
-
<span class="text-muted-foreground">{lang[interfaceLanguage.current].audioDescriptionLabel}</span>
|
|
330
|
-
{/if}
|
|
331
|
-
</div>
|
|
332
|
-
<div class="flex gap-1">
|
|
333
|
-
{#if file.audioDescriptionFileId}
|
|
334
|
-
<Button size="sm" variant="ghost" class="h-6 text-xs" onclick={() => {
|
|
335
|
-
remotes.updateMediaAccessibility({ fileId: file.id, audioDescriptionFileId: null });
|
|
336
|
-
file.audioDescriptionFileId = null;
|
|
337
|
-
}}>
|
|
338
|
-
{lang[interfaceLanguage.current].removeFile}
|
|
339
|
-
</Button>
|
|
340
|
-
{/if}
|
|
341
|
-
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (audioDescDialogOpen = true)}>
|
|
342
|
-
<Upload class="h-3 w-3 mr-1" />
|
|
343
|
-
{lang[interfaceLanguage.current].uploadAudioDescription}
|
|
344
|
-
</Button>
|
|
345
|
-
</div>
|
|
346
|
-
</div>
|
|
320
|
+
<!-- Filename -->
|
|
321
|
+
<div class="space-y-1.5">
|
|
322
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].fileNameLabel}</div>
|
|
323
|
+
<FileNameInput name={file.name} onUpdate={onNameUpdate} />
|
|
324
|
+
</div>
|
|
347
325
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
326
|
+
<!-- URL -->
|
|
327
|
+
<div class="space-y-1.5">
|
|
328
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].fileUrlLabel}</div>
|
|
329
|
+
<div class="flex items-stretch">
|
|
330
|
+
<input
|
|
331
|
+
readonly
|
|
332
|
+
value={fileUrl}
|
|
333
|
+
class="flex-1 min-w-0 rounded-l-lg bg-muted/60 border border-transparent px-2.5 py-1.5 font-mono text-xs text-foreground outline-none focus:border-primary focus:ring-2 focus:ring-primary/10 focus:bg-card"
|
|
334
|
+
/>
|
|
335
|
+
<button
|
|
336
|
+
type="button"
|
|
337
|
+
class="flex items-center justify-center w-9 rounded-r-lg bg-muted/60 border border-l-0 border-transparent text-text-light transition-colors hover:bg-lavender-lighter hover:text-primary"
|
|
338
|
+
onclick={() => clipboard.copy(fileUrl)}
|
|
339
|
+
aria-label="Kopiuj URL"
|
|
340
|
+
>
|
|
341
|
+
{#if clipboard.copied}
|
|
342
|
+
<Check class="h-3.5 w-3.5" />
|
|
353
343
|
{:else}
|
|
354
|
-
<
|
|
344
|
+
<Copy class="h-3.5 w-3.5" />
|
|
355
345
|
{/if}
|
|
356
|
-
|
|
357
|
-
</div>
|
|
358
|
-
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (posterDialogOpen = true)}>
|
|
359
|
-
{lang[interfaceLanguage.current].changePoster}
|
|
360
|
-
</Button>
|
|
346
|
+
</button>
|
|
361
347
|
</div>
|
|
362
348
|
</div>
|
|
363
|
-
{/if}
|
|
364
|
-
</div>
|
|
365
349
|
|
|
366
|
-
<!--
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
350
|
+
<!-- Alt text + focal point for images -->
|
|
351
|
+
{#if file.type === 'image'}
|
|
352
|
+
<div class="space-y-1.5">
|
|
353
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].fileAltLabel}</div>
|
|
354
|
+
<AltInput alt={file.alt} fileId={file.id} />
|
|
355
|
+
<p class="text-[11px] text-text-light leading-relaxed">{lang[interfaceLanguage.current].fileAltHint}</p>
|
|
356
|
+
</div>
|
|
357
|
+
<div class="space-y-1.5">
|
|
358
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].focalPointLabel}</div>
|
|
359
|
+
<FocalPointInput {file} />
|
|
360
|
+
</div>
|
|
372
361
|
{/if}
|
|
373
362
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
<
|
|
377
|
-
|
|
363
|
+
<!-- Accessibility section for video/audio -->
|
|
364
|
+
{#if file.type === 'video' || file.type === 'audio'}
|
|
365
|
+
<div class="space-y-3">
|
|
366
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light">{lang[interfaceLanguage.current].accessibilityLabel}</div>
|
|
367
|
+
|
|
368
|
+
<div class="flex items-center justify-between gap-2 rounded-lg border p-2">
|
|
369
|
+
<div class="flex items-center gap-2 text-xs">
|
|
370
|
+
{#if file.transcriptFileId}
|
|
371
|
+
<CircleCheck class="h-4 w-4 text-success" />
|
|
372
|
+
<span>{lang[interfaceLanguage.current].transcriptLabel}</span>
|
|
373
|
+
{:else}
|
|
374
|
+
<AlertTriangle class="h-4 w-4 text-warning" />
|
|
375
|
+
<span class="text-muted-foreground">{lang[interfaceLanguage.current].transcriptLabel}</span>
|
|
376
|
+
{/if}
|
|
377
|
+
</div>
|
|
378
|
+
<div class="flex gap-1">
|
|
379
|
+
{#if file.transcriptFileId}
|
|
380
|
+
<Button size="sm" variant="ghost" class="h-6 text-xs" onclick={() => {
|
|
381
|
+
remotes.updateMediaAccessibility({ fileId: file.id, transcriptFileId: null });
|
|
382
|
+
file.transcriptFileId = null;
|
|
383
|
+
}}>
|
|
384
|
+
{lang[interfaceLanguage.current].removeFile}
|
|
385
|
+
</Button>
|
|
386
|
+
{/if}
|
|
387
|
+
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (transcriptDialogOpen = true)}>
|
|
388
|
+
<Upload class="h-3 w-3 mr-1" />
|
|
389
|
+
{lang[interfaceLanguage.current].uploadTranscript}
|
|
390
|
+
</Button>
|
|
391
|
+
</div>
|
|
392
|
+
</div>
|
|
378
393
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
394
|
+
{#if file.type === 'video'}
|
|
395
|
+
<div class="flex items-center justify-between gap-2 rounded-lg border p-2">
|
|
396
|
+
<div class="flex items-center gap-2 text-xs">
|
|
397
|
+
{#if file.audioDescriptionFileId}
|
|
398
|
+
<CircleCheck class="h-4 w-4 text-success" />
|
|
399
|
+
<span>{lang[interfaceLanguage.current].audioDescriptionLabel}</span>
|
|
400
|
+
{:else}
|
|
401
|
+
<AlertTriangle class="h-4 w-4 text-warning" />
|
|
402
|
+
<span class="text-muted-foreground">{lang[interfaceLanguage.current].audioDescriptionLabel}</span>
|
|
403
|
+
{/if}
|
|
404
|
+
</div>
|
|
405
|
+
<div class="flex gap-1">
|
|
406
|
+
{#if file.audioDescriptionFileId}
|
|
407
|
+
<Button size="sm" variant="ghost" class="h-6 text-xs" onclick={() => {
|
|
408
|
+
remotes.updateMediaAccessibility({ fileId: file.id, audioDescriptionFileId: null });
|
|
409
|
+
file.audioDescriptionFileId = null;
|
|
410
|
+
}}>
|
|
411
|
+
{lang[interfaceLanguage.current].removeFile}
|
|
412
|
+
</Button>
|
|
413
|
+
{/if}
|
|
414
|
+
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (audioDescDialogOpen = true)}>
|
|
415
|
+
<Upload class="h-3 w-3 mr-1" />
|
|
416
|
+
{lang[interfaceLanguage.current].uploadAudioDescription}
|
|
417
|
+
</Button>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
385
420
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
421
|
+
<div class="flex items-center justify-between gap-2 rounded-lg border p-2">
|
|
422
|
+
<div class="flex items-center gap-2 text-xs">
|
|
423
|
+
{#if file.posterUrl}
|
|
424
|
+
<CircleCheck class="h-4 w-4 text-success" />
|
|
425
|
+
{:else}
|
|
426
|
+
<AlertTriangle class="h-4 w-4 text-warning" />
|
|
427
|
+
{/if}
|
|
428
|
+
<span class={file.posterUrl ? '' : 'text-muted-foreground'}>{lang[interfaceLanguage.current].posterLabel}</span>
|
|
429
|
+
</div>
|
|
430
|
+
<Button size="sm" variant="outline" class="h-6 text-xs" onclick={() => (posterDialogOpen = true)}>
|
|
431
|
+
{lang[interfaceLanguage.current].changePoster}
|
|
432
|
+
</Button>
|
|
433
|
+
</div>
|
|
434
|
+
{/if}
|
|
435
|
+
</div>
|
|
389
436
|
{/if}
|
|
437
|
+
</div>
|
|
390
438
|
|
|
391
|
-
|
|
392
|
-
|
|
439
|
+
<!-- Metadata footer -->
|
|
440
|
+
<div class="shrink-0 border-t bg-muted/20 px-5 py-4">
|
|
441
|
+
<div class="text-[11px] font-bold uppercase tracking-wide text-text-light mb-2">{lang[interfaceLanguage.current].metadataLabel}</div>
|
|
442
|
+
<div class="grid grid-cols-[auto_1fr] gap-x-3 gap-y-1 text-[13px]">
|
|
443
|
+
{#if file.mimeType}
|
|
444
|
+
<span class="text-text-light font-medium whitespace-nowrap">{lang[interfaceLanguage.current].mimeTypeLabel}</span>
|
|
445
|
+
<span class="font-medium text-foreground">{file.mimeType}</span>
|
|
446
|
+
{/if}
|
|
447
|
+
|
|
448
|
+
{#if file.width && file.height}
|
|
449
|
+
<span class="text-text-light font-medium whitespace-nowrap">{lang[interfaceLanguage.current].dimensionsLabel}</span>
|
|
450
|
+
<span class="font-medium text-foreground">{file.width} × {file.height} px</span>
|
|
451
|
+
{/if}
|
|
452
|
+
|
|
453
|
+
{#if file.duration}
|
|
454
|
+
<span class="text-text-light font-medium whitespace-nowrap">{lang[interfaceLanguage.current].durationLabel}</span>
|
|
455
|
+
<span class="font-medium text-foreground">
|
|
456
|
+
{Math.floor(file.duration / 60)}:{String(Math.floor(file.duration % 60)).padStart(2, '0')}
|
|
457
|
+
</span>
|
|
458
|
+
{/if}
|
|
459
|
+
|
|
460
|
+
{#if file.size}
|
|
461
|
+
<span class="text-text-light font-medium whitespace-nowrap">{lang[interfaceLanguage.current].sizeLabel}</span>
|
|
462
|
+
<span class="font-medium text-foreground">{formatFileSize(file.size)}</span>
|
|
463
|
+
{/if}
|
|
464
|
+
|
|
465
|
+
<span class="text-text-light font-medium whitespace-nowrap">{lang[interfaceLanguage.current].createdAtLabel}</span>
|
|
466
|
+
<span class="font-medium text-foreground">{new Date(file.createdAt).toLocaleDateString()}</span>
|
|
467
|
+
</div>
|
|
393
468
|
</div>
|
|
394
469
|
</div>
|
|
395
470
|
|
|
471
|
+
<!-- Delete confirmation -->
|
|
472
|
+
<AlertDialog.Root bind:open={deleteDialogOpen}>
|
|
473
|
+
<AlertDialog.Content>
|
|
474
|
+
<AlertDialog.Title>{lang[interfaceLanguage.current].deleteConfirmTitle}</AlertDialog.Title>
|
|
475
|
+
<AlertDialog.Description>{lang[interfaceLanguage.current].deleteConfirmDesc}</AlertDialog.Description>
|
|
476
|
+
<AlertDialog.Footer>
|
|
477
|
+
<AlertDialog.Cancel>{lang[interfaceLanguage.current].deleteCancel}</AlertDialog.Cancel>
|
|
478
|
+
<AlertDialog.Action
|
|
479
|
+
onclick={() => {
|
|
480
|
+
onDelete();
|
|
481
|
+
deleteDialogOpen = false;
|
|
482
|
+
}}
|
|
483
|
+
>
|
|
484
|
+
{lang[interfaceLanguage.current].fileDeleteLabel}
|
|
485
|
+
</AlertDialog.Action>
|
|
486
|
+
</AlertDialog.Footer>
|
|
487
|
+
</AlertDialog.Content>
|
|
488
|
+
</AlertDialog.Root>
|
|
489
|
+
|
|
396
490
|
<!-- Lightbox -->
|
|
397
491
|
{#if file.type === 'image'}
|
|
398
492
|
<Dialog.Root bind:open={lightboxOpen}>
|
|
399
493
|
<Dialog.Content class="max-w-[90vw] max-h-[90vh] p-2 bg-black/95 border-none">
|
|
400
|
-
<div class="
|
|
494
|
+
<div class="flex items-center justify-center rounded-lg overflow-hidden" style="background: repeating-conic-gradient(#2a2a2a 0% 25%, #1a1a1a 0% 50%) 50% / 20px 20px; padding: 8px;">
|
|
401
495
|
<img
|
|
402
496
|
src={file.url}
|
|
403
497
|
alt={file.alt || file.name}
|
|
@@ -408,8 +502,8 @@
|
|
|
408
502
|
</Dialog.Root>
|
|
409
503
|
{/if}
|
|
410
504
|
|
|
411
|
-
<!--
|
|
412
|
-
{#if file.type === 'video'}
|
|
505
|
+
<!-- Transcript dialog (video + audio) -->
|
|
506
|
+
{#if file.type === 'video' || file.type === 'audio'}
|
|
413
507
|
<Dialog.Root bind:open={transcriptDialogOpen}>
|
|
414
508
|
<Dialog.Content class="max-w-5xl! sm:max-w-5xl!">
|
|
415
509
|
<Dialog.Header>
|
|
@@ -418,7 +512,10 @@
|
|
|
418
512
|
<MediaSelector bind:selected={transcriptSelected} />
|
|
419
513
|
</Dialog.Content>
|
|
420
514
|
</Dialog.Root>
|
|
515
|
+
{/if}
|
|
421
516
|
|
|
517
|
+
<!-- Audio description + poster dialogs (video only) -->
|
|
518
|
+
{#if file.type === 'video'}
|
|
422
519
|
<Dialog.Root bind:open={audioDescDialogOpen}>
|
|
423
520
|
<Dialog.Content class="max-w-5xl! sm:max-w-5xl!">
|
|
424
521
|
<Dialog.Header>
|
|
@@ -437,18 +534,3 @@
|
|
|
437
534
|
</Dialog.Content>
|
|
438
535
|
</Dialog.Root>
|
|
439
536
|
{/if}
|
|
440
|
-
|
|
441
|
-
<style>
|
|
442
|
-
.checkered-lightbox {
|
|
443
|
-
background-color: #1a1a1a;
|
|
444
|
-
background-image:
|
|
445
|
-
linear-gradient(45deg, #2a2a2a 25%, transparent 25%),
|
|
446
|
-
linear-gradient(-45deg, #2a2a2a 25%, transparent 25%),
|
|
447
|
-
linear-gradient(45deg, transparent 75%, #2a2a2a 75%),
|
|
448
|
-
linear-gradient(-45deg, transparent 75%, #2a2a2a 75%);
|
|
449
|
-
background-size: 20px 20px;
|
|
450
|
-
background-position: 0 0, 0 10px, 10px -10px, -10px 0px;
|
|
451
|
-
border-radius: 8px;
|
|
452
|
-
padding: 8px;
|
|
453
|
-
}
|
|
454
|
-
</style>
|