mirror of
https://codeberg.org/PLG-Development/PLG-MuDiCS
synced 2026-07-06 00:47:09 +00:00
chore(control): add progress_bar in InodeElement
This commit is contained in:
@@ -6,7 +6,12 @@
|
|||||||
get_shifted_color
|
get_shifted_color
|
||||||
} from '$lib/ts/stores/ui_behavior';
|
} from '$lib/ts/stores/ui_behavior';
|
||||||
import Button from '$lib/components/Button.svelte';
|
import Button from '$lib/components/Button.svelte';
|
||||||
import { supported_file_type_icon, type Inode, get_file_primary_key } from '$lib/ts/types';
|
import {
|
||||||
|
supported_file_type_icon,
|
||||||
|
type Inode,
|
||||||
|
get_file_primary_key,
|
||||||
|
type FileOnDisplay
|
||||||
|
} from '$lib/ts/types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
is_selected,
|
is_selected,
|
||||||
@@ -26,6 +31,7 @@
|
|||||||
import { run_on_all_selected_displays } from '$lib/ts/stores/displays';
|
import { run_on_all_selected_displays } from '$lib/ts/stores/displays';
|
||||||
import { get_thumbnail_url } from '$lib/ts/stores/thumbnails';
|
import { get_thumbnail_url } from '$lib/ts/stores/thumbnails';
|
||||||
import { liveQuery, type Observable } from 'dexie';
|
import { liveQuery, type Observable } from 'dexie';
|
||||||
|
import { db } from '$lib/ts/files_display.db';
|
||||||
|
|
||||||
let { file, not_interactable = false }: { file: Inode; not_interactable?: boolean } = $props();
|
let { file, not_interactable = false }: { file: Inode; not_interactable?: boolean } = $props();
|
||||||
|
|
||||||
@@ -37,8 +43,19 @@
|
|||||||
missing_colliding_displays_ids = liveQuery(() => get_missing_colliding_display_ids(file, s));
|
missing_colliding_displays_ids = liveQuery(() => get_missing_colliding_display_ids(file, s));
|
||||||
});
|
});
|
||||||
|
|
||||||
let thumbnail_url = liveQuery(() => get_thumbnail_url(get_file_primary_key(file)));
|
let loading_data:
|
||||||
|
| Observable<{
|
||||||
|
is_loading: boolean;
|
||||||
|
total_percentage: number;
|
||||||
|
display_data: { is_loading: boolean; percentage: number }[];
|
||||||
|
}>
|
||||||
|
| undefined = $state();
|
||||||
|
$effect(() => {
|
||||||
|
const d = $selected_display_ids;
|
||||||
|
loading_data = liveQuery(() => get_loading_data(get_file_primary_key(file), d));
|
||||||
|
});
|
||||||
|
|
||||||
|
let thumbnail_url = liveQuery(() => get_thumbnail_url(get_file_primary_key(file)));
|
||||||
let date_mapping: Observable<Record<string, Date>> = liveQuery(() =>
|
let date_mapping: Observable<Record<string, Date>> = liveQuery(() =>
|
||||||
get_date_mapping(get_file_primary_key(file))
|
get_date_mapping(get_file_primary_key(file))
|
||||||
);
|
);
|
||||||
@@ -52,21 +69,28 @@
|
|||||||
|
|
||||||
if (keys.length === 1) return get_formated_created_string(date_mapping[keys[0]], full_string);
|
if (keys.length === 1) return get_formated_created_string(date_mapping[keys[0]], full_string);
|
||||||
|
|
||||||
let out = "";
|
let out = '';
|
||||||
let is_different = false;
|
let is_different = false;
|
||||||
const first_formated_created_string = get_formated_created_string(date_mapping[keys[0]], full_string);
|
const first_formated_created_string = get_formated_created_string(
|
||||||
|
date_mapping[keys[0]],
|
||||||
|
full_string
|
||||||
|
);
|
||||||
out += `${keys[0]}: ${first_formated_created_string}`;
|
out += `${keys[0]}: ${first_formated_created_string}`;
|
||||||
|
|
||||||
for (const key of keys.splice(0, 1)) {
|
for (const key of keys.splice(0, 1)) {
|
||||||
const current_formated_created_string = get_formated_created_string(date_mapping[key], full_string);
|
const current_formated_created_string = get_formated_created_string(
|
||||||
if (!is_different && current_formated_created_string !== first_formated_created_string) is_different = true;
|
date_mapping[key],
|
||||||
out += `\n${key}: ${current_formated_created_string}`
|
full_string
|
||||||
|
);
|
||||||
|
if (!is_different && current_formated_created_string !== first_formated_created_string)
|
||||||
|
is_different = true;
|
||||||
|
out += `\n${key}: ${current_formated_created_string}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (full_string) {
|
if (full_string) {
|
||||||
return is_different ? out : first_formated_created_string;
|
return is_different ? out : first_formated_created_string;
|
||||||
} else {
|
} else {
|
||||||
return is_different ? "versch." : first_formated_created_string;
|
return is_different ? 'versch.' : first_formated_created_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +119,7 @@
|
|||||||
|
|
||||||
function get_grayed_out_text_color_strings(is_selected: boolean): string {
|
function get_grayed_out_text_color_strings(is_selected: boolean): string {
|
||||||
if (not_interactable) return 'text-stone-400';
|
if (not_interactable) return 'text-stone-400';
|
||||||
|
if ($loading_data?.is_loading) return 'text-white/20';
|
||||||
const color = is_selected ? 'text-stone-600' : 'text-stone-400';
|
const color = is_selected ? 'text-stone-600' : 'text-stone-400';
|
||||||
const factor = is_selected ? -1 : 1;
|
const factor = is_selected ? -1 : 1;
|
||||||
return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
|
return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
|
||||||
@@ -102,13 +127,14 @@
|
|||||||
|
|
||||||
function get_grayed_out_border_color_strings(is_selected: boolean): string {
|
function get_grayed_out_border_color_strings(is_selected: boolean): string {
|
||||||
if (not_interactable) return 'border-stone-550';
|
if (not_interactable) return 'border-stone-550';
|
||||||
|
if ($loading_data?.is_loading) return 'border-white/10';
|
||||||
const color = is_selected ? 'border-stone-450' : 'border-stone-550';
|
const color = is_selected ? 'border-stone-450' : 'border-stone-550';
|
||||||
const factor = is_selected ? 1 : 1;
|
const factor = is_selected ? 1 : 1;
|
||||||
return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
|
return `${color} group-hover:${get_shifted_color(color, factor * 100)} group-active:${get_shifted_color(color, factor * 150)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function onclick(e: Event) {
|
function onclick(e: Event) {
|
||||||
if (not_interactable) return;
|
if (not_interactable || $loading_data?.is_loading) return;
|
||||||
select(selected_file_ids, get_file_primary_key(file), 'toggle');
|
select(selected_file_ids, get_file_primary_key(file), 'toggle');
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
@@ -121,6 +147,73 @@
|
|||||||
await run_on_all_selected_displays(open_file, true, path_to_file);
|
await run_on_all_selected_displays(open_file, true, path_to_file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_main_classes(): string {
|
||||||
|
let out = '';
|
||||||
|
|
||||||
|
if ($loading_data?.is_loading) {
|
||||||
|
out += 'bg-stone-700 text-white/30';
|
||||||
|
} else {
|
||||||
|
out += get_selectable_color_classes(
|
||||||
|
!not_interactable && is_selected(get_file_primary_key(file), $selected_file_ids),
|
||||||
|
{
|
||||||
|
bg: true,
|
||||||
|
hover: !not_interactable,
|
||||||
|
active: !not_interactable,
|
||||||
|
text: true
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not_interactable) {
|
||||||
|
out += ' rounded-lg';
|
||||||
|
} else if ($loading_data?.is_loading) {
|
||||||
|
out += ' rounded-r-lg';
|
||||||
|
} else {
|
||||||
|
out += ' rounded-r-lg cursor-pointer';
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function get_loading_data(
|
||||||
|
file_primary_key: string,
|
||||||
|
selected_display_ids: string[]
|
||||||
|
): Promise<{
|
||||||
|
is_loading: boolean;
|
||||||
|
total_percentage: number;
|
||||||
|
display_data: { is_loading: boolean; percentage: number }[];
|
||||||
|
}> {
|
||||||
|
const file_on_display_data: FileOnDisplay[] = await db.files_on_display
|
||||||
|
.where('file_primary_key')
|
||||||
|
.equals(file_primary_key)
|
||||||
|
.filter((e) => selected_display_ids.includes(e.display_id))
|
||||||
|
.toArray();
|
||||||
|
if (file_on_display_data.length === 0) {
|
||||||
|
return {
|
||||||
|
is_loading: true,
|
||||||
|
total_percentage: 0,
|
||||||
|
display_data: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const display_data = [];
|
||||||
|
let is_loading = false;
|
||||||
|
let percentage_sum = 0;
|
||||||
|
for (const fod of file_on_display_data) {
|
||||||
|
if (!is_loading) is_loading = fod.is_loading;
|
||||||
|
percentage_sum += fod.percentage;
|
||||||
|
display_data.push({
|
||||||
|
is_loading: fod.is_loading,
|
||||||
|
percentage: fod.percentage
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let total_percentage = percentage_sum / display_data.length;
|
||||||
|
return {
|
||||||
|
is_loading,
|
||||||
|
total_percentage,
|
||||||
|
display_data
|
||||||
|
};
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div data-testid="inode" class="flex flex-row h-{$current_height.file} w-full">
|
<div data-testid="inode" class="flex flex-row h-{$current_height.file} w-full">
|
||||||
@@ -178,27 +271,25 @@
|
|||||||
if (e.key === 'Enter' || e.key === ' ') onclick(e);
|
if (e.key === 'Enter' || e.key === ' ') onclick(e);
|
||||||
}}
|
}}
|
||||||
{onclick}
|
{onclick}
|
||||||
class="{get_selectable_color_classes(
|
class="{get_main_classes()} relative transition-colors duration-200 gap-4 flex flex-row justify-between group w-full min-w-0"
|
||||||
!not_interactable && is_selected(get_file_primary_key(file), $selected_file_ids),
|
|
||||||
{
|
|
||||||
bg: true,
|
|
||||||
hover: !not_interactable,
|
|
||||||
active: !not_interactable,
|
|
||||||
text: true
|
|
||||||
}
|
|
||||||
)} {not_interactable
|
|
||||||
? 'rounded-lg'
|
|
||||||
: 'rounded-r-lg cursor-pointer'} transition-colors duration-200 gap-4 flex flex-row justify-between group w-full min-w-0"
|
|
||||||
>
|
>
|
||||||
<div class="flex flex-row gap-2 min-w-0 w-full">
|
{#if $loading_data?.is_loading}
|
||||||
|
<!-- <div class="pointer-events-none absolute inset-0"> -->
|
||||||
|
<div
|
||||||
|
class="absolute pointer-events-none inset-y-0 left-0 transition-[width] duration-200 bg-stone-600 rounded-r-lg"
|
||||||
|
style={`width: ${$loading_data.total_percentage}%;`}
|
||||||
|
></div>
|
||||||
|
<!-- </div> -->
|
||||||
|
{/if}
|
||||||
|
<div class="flex flex-row gap-2 min-w-0 w-full z-10">
|
||||||
<div class="aspect-square rounded-md flex justify-center items-center">
|
<div class="aspect-square rounded-md flex justify-center items-center">
|
||||||
{#if is_folder}
|
{#if is_folder}
|
||||||
<Folder class="size-full p-2" />
|
<Folder class="size-full p-2" />
|
||||||
{:else if $thumbnail_url || null}
|
{:else if $thumbnail_url || null}
|
||||||
<img
|
<img
|
||||||
src={$thumbnail_url || null}
|
src={$thumbnail_url || null}
|
||||||
alt="file_thumbnail"
|
alt="ERR"
|
||||||
class="object-contain size-full select-none block p-1 rounded-lg"
|
class="object-contain size-full select-none block p-1 rounded-lg text-center content-center text-red-300"
|
||||||
draggable="false"
|
draggable="false"
|
||||||
/>
|
/>
|
||||||
{:else if supported_file_type_icon[get_file_type(file)?.display_name || '']}
|
{:else if supported_file_type_icon[get_file_type(file)?.display_name || '']}
|
||||||
@@ -215,7 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class=" p-1 flex flex-row items-center gap-1 pr-1 {get_grayed_out_text_color_strings(
|
class=" p-1 flex flex-row items-center gap-1 pr-1 z-10 {get_grayed_out_text_color_strings(
|
||||||
is_selected(get_file_primary_key(file), $selected_file_ids)
|
is_selected(get_file_primary_key(file), $selected_file_ids)
|
||||||
)} duration-200 transition-colors"
|
)} duration-200 transition-colors"
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user