To connect your TMDB account, log in via the link below and then click "Complete Connection".
@@ -313,7 +314,7 @@
-
+
Connect to Jellyfin to watch movies and tv shows.
@@ -330,7 +331,7 @@
{#if users.length}
(openTab = Tabs.SelectUser)}
+ on:clickOrSelect={() => tab.set(Tabs.SelectUser)}
>
User
@@ -342,20 +343,15 @@
{/if}
-
+
{#if jellyfinBaseUrl && jellyfinApiKey && jellyfinUser}
{:else}
-
+
{/if}
- (openTab = Tabs.Jellyfin)}
- class={tabContainer}
- >
+ tab.set(Tabs.Jellyfin)} class={tabContainer}>
{#await jellyfinUsers then users}
{#each users as user}
@@ -363,7 +359,7 @@
selected={user?.Id === jellyfinUser?.Id}
on:clickOrSelect={() => {
jellyfinUser = user;
- openTab = Tabs.Jellyfin;
+ tab.set(Tabs.Jellyfin);
}}
>
{user.Name}
@@ -372,7 +368,7 @@
{/await}
-
+
Connect to Sonarr for requesting and managing tv shows.
@@ -386,16 +382,16 @@
{/if}
-
+
{#if sonarrBaseUrl && sonarrApiKey}
{:else}
-
+
{/if}
-
+
Connect to Radarr for requesting and managing movies.
@@ -409,7 +405,7 @@
{/if}
-
+
{#if radarrBaseUrl && radarrApiKey}
{:else}
diff --git a/src/lib/selectable.ts b/src/lib/selectable.ts
index 609cdb7..d7e7529 100644
--- a/src/lib/selectable.ts
+++ b/src/lib/selectable.ts
@@ -81,6 +81,8 @@ export type NavigationHandler = (
) => void;
export type KeyEventHandler = (selectable: Selectable, options: KeyEventOptions) => void;
+export type ActiveChildStore = typeof Selectable.prototype.activeChild;
+
export class Selectable {
id: number;
name: string;
@@ -109,6 +111,22 @@ export class Selectable {
static focusedObject: Writable = writable(undefined);
focusIndex: Writable = writable(0);
+
+ activeChild = (() => {
+ const store = derived(this.focusIndex, (focusIndex) => {
+ return this.children[focusIndex];
+ });
+
+ const set = (selectable: Selectable) => {
+ const index = this.children.indexOf(selectable);
+ if (index !== -1) this.focusIndex.set(index);
+ };
+
+ return {
+ subscribe: store.subscribe,
+ set
+ };
+ })();
hasFocus: Readable = derived(Selectable.focusedObject, ($focusedObject) => {
return $focusedObject === this;
});
@@ -219,6 +237,24 @@ export class Selectable {
return false;
}
+ activate() {
+ const parent = this.parent;
+ if (!parent) {
+ console.error('No parent, undefined behavior?');
+ return;
+ }
+
+ const parentHasFocus = get(parent.hasFocusWithin);
+
+ if (parentHasFocus) {
+ this.focus();
+ } else {
+ const index = parent.children.indexOf(this);
+ if (index === -1) console.error('Child not found in parent when activating', this, parent);
+ this.parent?.focusIndex.update((prev) => (index >= 0 ? index : prev));
+ }
+ }
+
/**
* @returns {boolean} whether the selectable is focusable
*/
@@ -623,13 +659,15 @@ export class Selectable {
hasFocusWithin: Readable;
registerer: Registerer;
focusIndex: Writable;
+ activeChild: ActiveChildStore;
} {
return {
container: this,
hasFocus: this.hasFocus,
hasFocusWithin: this.hasFocusWithin,
registerer: this.getRegisterer(),
- focusIndex: this.focusIndex
+ focusIndex: this.focusIndex,
+ activeChild: this.activeChild
};
}