Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions src/apps/components/apppermissions/AppPermissions.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

const { process }: { process: AppPermissionsRuntime } = $props();
const { targetApp } = process;
const { Configuration } = Permissions!;
const { Storage } = Permissions!;

let permissionId = $state<string>("");

onMount(() => {
Configuration.subscribe((permissions) => {
Storage.subscribe((permissions) => {
const reg = permissions?.registration ?? {};
permissionId = Object.keys(reg).find((key) => reg[key] === $targetApp.id) ?? "";
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import { onMount } from "svelte";

const { id, permissionId }: { id: PermissionString; permissionId: string } = $props();
const { Configuration } = Permissions!;
const { Storage } = Permissions!;

const options = ["Unset", "Allow", "Deny"] as const;
type Option = (typeof options)[number];

let option = $state<Option>("Unset");

onMount(() => {
Configuration.subscribe((permissions) => {
Storage.subscribe((permissions) => {
const state = permissions.allowed[permissionId]?.includes(id)
? "Allow"
: permissions.denied[permissionId]?.includes(id)
Expand Down
2 changes: 1 addition & 1 deletion src/apps/components/iconpicker/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class IconPickerRuntime extends AppProcess {
const iconService = Daemon?.serviceHost?.getService<IconService>("IconService");

if (!iconService) return false;
this.store = iconService.Configuration();
this.store = iconService.Icons();
this.groups = iconService.getGroupedIcons();
}

Expand Down
10 changes: 5 additions & 5 deletions src/apps/components/wallpaper/Wallpaper/DesktopIcon.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@
let movingX = $state<number>();
let movingY = $state<number>();

const { userPreferences, Configuration, selected, orphaned } = process;
const { userPreferences, Positions, selected, orphaned } = process;

async function updatePos() {
const pos = $Configuration[`icon$${identifier}`] as {
const pos = $Positions[`icon$${identifier}`] as {
x: number;
y: number;
};
Expand All @@ -64,8 +64,8 @@

const { x, y } = target.getBoundingClientRect();

if (!Object.values($Configuration).filter((pos) => pos.x === x && pos.y === y).length) {
$Configuration[`icon$${identifier}`] = {
if (!Object.values($Positions).filter((pos) => pos.x === x && pos.y === y).length) {
$Positions[`icon$${identifier}`] = {
x,
y,
};
Expand All @@ -87,7 +87,7 @@
}

onMount(updatePos);
Configuration.subscribe(updatePos);
Positions.subscribe(updatePos);
</script>

<!-- svelte-ignore event_directive_deprecated -->
Expand Down
81 changes: 13 additions & 68 deletions src/apps/components/wallpaper/runtime.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { AppProcess } from "$ts/apps/process";
import { ConfigurationBuilder } from "$ts/config";
import { Daemon } from "$ts/daemon";
import { Env, Fs, SysDispatch } from "$ts/env";
import { UserPaths } from "$ts/user/store";
import { arrayBufferToText, textToBlob } from "$ts/util/convert";
import { MessageBox } from "$ts/util/dialog";
import { getItemNameFromPath, join } from "$ts/util/fs";
import { tryJsonParse } from "$ts/util/json";
import { Store } from "$ts/writable";
import type { AppContextMenu, AppProcessData } from "$types/app";
import type { DirectoryReadReturn } from "$types/fs";
Expand All @@ -23,7 +22,14 @@ export class WallpaperRuntime extends AppProcess {
orphaned = Store<string[]>([]);
loading = Store<boolean>(false);
directory: string;
Configuration = Store<DesktopIcons>({});
Positions = Store<DesktopIcons>({});
Configuration = new ConfigurationBuilder<DesktopIcons>()
.ForProcess(this)
.ReadsFrom(this.Positions)
.WritesTo(this.CONFIG_PATH)
.WithDefaults({})
.WithCooldown(500)
.Build();

public contextMenu: AppContextMenu = WallpaperContextMenu(this);

Expand All @@ -45,18 +51,7 @@ export class WallpaperRuntime extends AppProcess {
}

async start() {
const migrated = await this.migrateDesktopIcons();
if (!migrated) await this.loadConfiguration();

let firstSub = false;

this.Configuration.subscribe((v) => {
if (!firstSub) {
firstSub = true;
return;
}
this.writeConfiguration(v);
});
await this.Configuration.initialize();
}

async render() {
Expand Down Expand Up @@ -105,7 +100,7 @@ export class WallpaperRuntime extends AppProcess {

findAndDeleteOrphans(contents: DirectoryReadReturn | undefined) {
const orphaned = this.orphaned();
const config = this.Configuration();
const config = this.Positions();
let orphanedCount = 0;

for (const id of Object.keys(config)) {
Expand All @@ -123,7 +118,7 @@ export class WallpaperRuntime extends AppProcess {
}
}

if (orphanedCount) this.Configuration.set(config);
if (orphanedCount) this.Positions.set(config);
this.orphaned.set(orphaned);
}

Expand All @@ -133,7 +128,7 @@ export class WallpaperRuntime extends AppProcess {
if (!wrapper) return { x: 0, y: 0 };

return new Promise((r) => {
this.Configuration.update((v) => {
this.Positions.update((v) => {
function resolve(x: number, y: number) {
r({ x, y });
v[`icon$${identifier}`] = { x, y };
Expand Down Expand Up @@ -247,55 +242,5 @@ export class WallpaperRuntime extends AppProcess {
prog.mutDone(+1);
}

//#endregion
//#region CONFIGURATION

async loadConfiguration() {
this.Log(`Loading configuration`);

try {
const contents = await Fs.readFile(this.CONFIG_PATH);
if (!contents) return await this.writeConfiguration({});

const json = tryJsonParse<DesktopIcons>(arrayBufferToText(contents));
if (!json || typeof json === "string") return await this.writeConfiguration({});

this.Configuration.set(json);
} catch {}
}

async writeConfiguration(data: DesktopIcons) {
this.Log(`Writing configuration`);

await Fs.writeFile(this.CONFIG_PATH, textToBlob(JSON.stringify(data, null, 2)));

return data;
}

// 7.0.5 -> 7.0.6+
// Migration of desktop icons from the preferences to a dedicated file in U:/System
async migrateDesktopIcons() {
this.Log(`migrateDesktopIcons`);

const migrationPath = join(UserPaths.Migrations, "DeskIconMig-706.lock");
const pref = this.userPreferences().appPreferences.desktopIcons;
const migration = await Fs.stat(migrationPath);

if (pref && !migration) {
await this.writeConfiguration(pref);
this.Configuration.set(pref);

this.userPreferences.update((v) => {
delete v.appPreferences.desktopIcons;
return v;
});

await Fs.writeFile(migrationPath, textToBlob(`${Date.now()}`));
return true;
}

return false;
}

//#endregion
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
const { process }: { process: FileManagerRuntime } = $props();
const { userPreferences } = process;
const service = Daemon.serviceHost?.getService<RecentFilesService>("RecentFilesSvc");
const Configuration = service?.Configuration;
const Rrecents = service?.Recents;

let selected = $state<string>("");
</script>

{#if Configuration}
{#if Rrecents}
<section class="recent-files">
<button
class="expander"
Expand All @@ -26,7 +26,7 @@
{
caption: "Clear recents",
icon: "x",
action: () => service.Configuration.set([]),
action: () => service.Recents.set([]),
},
],
process,
Expand All @@ -37,10 +37,10 @@
</button>
{#if $userPreferences.appPreferences.fileManager.myExpandRecents}
<div class="content">
{#if !$Configuration?.length}
{#if !$Rrecents?.length}
<p class="empty">The files you open will appear in this list.</p>
{:else}
{#each $Configuration as path (path)}
{#each $Rrecents as path (path)}
<RecentFile {path} {service} {process} bind:selected />
{/each}
{/if}
Expand Down
8 changes: 4 additions & 4 deletions src/apps/user/iconeditor/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class IconEditorRuntime extends AppProcess {
async start() {
this.iconService = Daemon?.serviceHost?.getService<IconService>("IconService");
this.setGroups();
this.icons.set({ ...(this.iconService?.Configuration() || {}) });
this.icons.set({ ...(this.iconService?.Icons() || {}) });
this.icons.subscribe(() => {
this.hasChanges.set(true);
this.updateFiltered();
Expand All @@ -49,7 +49,7 @@ export class IconEditorRuntime extends AppProcess {
);

if (saveChanges) {
this.iconService?.Configuration.set({ ...this.icons() });
this.iconService?.Icons.set({ ...this.icons() });
this.hasChanges.set(false);
}

Expand All @@ -60,7 +60,7 @@ export class IconEditorRuntime extends AppProcess {

revert() {
this.Log(`Reverting changes`);
this.icons.set({ ...(this.iconService?.Configuration() || {}) });
this.icons.set({ ...(this.iconService?.Icons() || {}) });
this.setGroups();
this.selectedIcon.set("");
this.selectedGroup.set("");
Expand Down Expand Up @@ -88,7 +88,7 @@ export class IconEditorRuntime extends AppProcess {
async save() {
this.Log(`Saving changes`);

this.iconService?.Configuration.set({ ...this.icons() });
this.iconService?.Icons.set({ ...this.icons() });
this.hasChanges.set(false);
await this.closeWindow();

Expand Down
35 changes: 8 additions & 27 deletions src/apps/user/mediaplayer/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { MediaPlayerAltMenu } from "./altmenu";
import TrayPopup from "./MediaPlayer/TrayPopup.svelte";
import { LoopMode, type AudioFileMetadata, type MetadataConfiguration, type PlayerState } from "./types";
import { CommandResult } from "$ts/result";
import { ConfigurationBuilder } from "$ts/config";

export class MediaPlayerRuntime extends AppProcess {
private readonly METADATA_PATH = join(UserPaths.Configuration, "MediaPlayer", "Metadata.json");
Expand All @@ -38,6 +39,12 @@ export class MediaPlayerRuntime extends AppProcess {
CurrentCoverUrl = Store<string | undefined>();
LoadingMetadata = Store<boolean>(false);
mediaSpecificAccentColor = Store<string>("");
Configuration = new ConfigurationBuilder()
.ForProcess(this)
.ReadsFrom(this.MetadataConfiguration)
.WritesTo(this.METADATA_PATH)
.WithDefaults({})
.Build();

override contextMenu: AppContextMenu = {
player: [
Expand Down Expand Up @@ -111,14 +118,8 @@ export class MediaPlayerRuntime extends AppProcess {
protected async start(): Promise<any> {
await Fs.createDirectory(getParentDirectory(this.METADATA_PATH));
await Fs.createDirectory(this.COVERIMAGES_PATH);
await this.readConfiguration();
await this.Configuration.initialize();

let firstSub = false;
this.MetadataConfiguration.subscribe((v) => {
if (!firstSub) return (firstSub = true);

this.writeConfiguration(v);
});
this.CurrentMediaMetadata.subscribe((v) => {
if (!v?.title) return;

Expand Down Expand Up @@ -588,26 +589,6 @@ export class MediaPlayerRuntime extends AppProcess {
//#endregion
//#region METADATA

async readConfiguration() {
try {
const content = await Fs.readFile(this.METADATA_PATH);
if (!content) throw new Error("Failed to read file contents");

const json = tryJsonParse(arrayBufferToText(content));
if (!json || typeof json === "string") throw new Error("File contents could not be parsed as JSON");

this.MetadataConfiguration.set(json);
} catch {
return await this.writeConfiguration({});
}
}

async writeConfiguration(configuration: MetadataConfiguration) {
this.Log(`writeConfiguration`);

await Fs.writeFile(this.METADATA_PATH, textToBlob(JSON.stringify(configuration, null, 2)), undefined, false);
}

async normalizeMetadata(meta: IAudioMetadata): Promise<AudioFileMetadata> {
this.Log(`normalizeMetadata`);

Expand Down
5 changes: 5 additions & 0 deletions src/interfaces/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface IConfigurator<T = object> {
readConfiguration(): Promise<T>;
writeConfiguration(configuration?: T): Promise<T>;
initialize(): Promise<void>;
}
6 changes: 3 additions & 3 deletions src/interfaces/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import type {
} from "$types/fs";
import type { PermissionStorage } from "$types/permission";
import type { ReadableStore } from "$types/writable";
import type { IConfigurator } from "./config";
import type { IFilesystemDrive } from "./fs";
import type { IProcess } from "./process";

export interface IPermissionHandler {
_criticalProcess: boolean;
Configuration: ReadableStore<PermissionStorage>;
readConfiguration(): Promise<void>;
writeConfiguration(config: PermissionStorage): Promise<void>;
Storage: ReadableStore<PermissionStorage>;
Configuration: IConfigurator<PermissionStorage>;
hasPermission(process: IProcess, permission: PermissionString): boolean;
grantPermission(process: IProcess, permission: PermissionString): void;
revokePermission(process: IProcess, permission: PermissionString): void;
Expand Down
4 changes: 1 addition & 3 deletions src/interfaces/services/IconService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ export interface IIconService extends IBaseService {
FILE_CACHE: Record<string, string>;
ICON_TYPES: string[];
DEFAULT_ICON: string;
Configuration: ReadableStore<Record<string, string>>;
Icons: ReadableStore<Record<string, string>>;
start(): Promise<void>;
loadConfiguration(): Promise<Record<string, string>>;
writeConfiguration(config: Record<string, string>): Promise<Record<string, string>>;
defaultConfiguration(): Record<string, string>;
getIcon(id: string, noCache?: boolean): Promise<string>;
getIconCached(id: string): string;
Expand Down
2 changes: 0 additions & 2 deletions src/interfaces/services/MigrationSvc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,4 @@ export interface IMigrationService extends IBaseService {
MIGRATIONS: IMigrationNodeConstructor[];
runMigrations(cb?: MigrationStatusCallback): Promise<Record<string, MigrationResult>>;
runMigration(migration: IMigrationNodeConstructor, cb?: MigrationStatusCallback): Promise<MigrationResult>;
loadConfiguration(): Promise<Record<string, number>>;
writeConfiguration(config: Record<string, number>): Promise<Record<string, number>>;
}
2 changes: 0 additions & 2 deletions src/interfaces/services/RecentFilesSvc.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import type { IBaseService } from "$interfaces/service";

export interface IRecentFilesService extends IBaseService {
loadConfiguration(): Promise<void>;
writeConfiguration(configuration: string[]): Promise<void>;
addToRecents(path: string): boolean;
removeFromRecents(path: string): boolean;
getRecents(): string[];
Expand Down
Loading