From 8e54d7f7cc19905ea967d315a4ab496888321769 Mon Sep 17 00:00:00 2001 From: Dawid Urbas Date: Wed, 24 Apr 2024 18:41:56 +0200 Subject: [PATCH 1/2] Add UI --- .../src/lib/components/AppDetailsPanel.svelte | 34 +++++ src/renderer/src/lib/components/TopBar.svelte | 3 + src/renderer/src/lib/components/index.ts | 2 + src/renderer/src/lib/const/launcher.ts | 1 - src/renderer/src/lib/const/menu.ts | 2 - src/renderer/src/lib/helpers/index.ts | 1 + src/renderer/src/lib/helpers/navigation.ts | 38 ++++++ src/renderer/src/lib/helpers/other.ts | 11 -- src/renderer/src/lib/icons/BackArrow.svelte | 9 ++ src/renderer/src/lib/icons/Warning.svelte | 4 +- src/renderer/src/lib/icons/index.ts | 1 + src/renderer/src/lib/locale/en/common.json | 3 +- .../src/lib/modal/AddPublisher.svelte | 4 +- src/renderer/src/routes/(main)/+layout.svelte | 121 +++++++++++++++++- .../routes/(main)/app-store/+layout.svelte | 23 ---- .../src/routes/(main)/app-store/+page.svelte | 15 ++- .../(main)/app-store/[slug]/+layout@.svelte | 22 ++++ .../(main)/app-store/[slug]/+page.svelte | 29 ++--- .../app-store/components/AppCard.svelte | 2 +- .../components/InstallFromDeviceCard.svelte | 2 +- .../src/routes/(main)/apps-view/+page.svelte | 30 ----- .../(main)/components/MainHeader.svelte | 118 ----------------- .../(splash)/confirm-password/+page.svelte | 2 +- .../src/routes/settings/+layout.svelte | 6 +- src/renderer/src/routes/settings/+page.svelte | 51 +------- .../src/routes/settings/[slug]/+layout.ts | 1 + .../src/routes/settings/[slug]/+page.svelte | 54 ++++++++ .../routes/settings/components/DevMenu.svelte | 10 +- .../settings/components/RegularMenu.svelte | 21 ++- .../routes/settings/components/TopBar.svelte | 4 +- .../src/routes/settings/dev/+page.svelte | 109 ++++++++++++---- .../routes/settings/dev/[slug]/+layout.svelte | 23 ++++ .../src/routes/settings/dev/[slug]/+layout.ts | 1 + .../routes/settings/dev/[slug]/+page.svelte | 53 ++++++++ .../routes/settings/dev/add-app/+page.svelte | 89 ------------- .../dev/components/ReleasesCard.svelte | 58 --------- .../routes/settings/dev/components/index.ts | 1 - src/renderer/tailwind.config.ts | 5 +- src/renderer/theme.ts | 22 ++-- 39 files changed, 508 insertions(+), 477 deletions(-) create mode 100644 src/renderer/src/lib/components/AppDetailsPanel.svelte create mode 100644 src/renderer/src/lib/components/TopBar.svelte create mode 100644 src/renderer/src/lib/helpers/navigation.ts create mode 100644 src/renderer/src/lib/icons/BackArrow.svelte delete mode 100644 src/renderer/src/routes/(main)/app-store/+layout.svelte create mode 100644 src/renderer/src/routes/(main)/app-store/[slug]/+layout@.svelte delete mode 100644 src/renderer/src/routes/(main)/components/MainHeader.svelte create mode 100644 src/renderer/src/routes/settings/[slug]/+layout.ts create mode 100644 src/renderer/src/routes/settings/[slug]/+page.svelte create mode 100644 src/renderer/src/routes/settings/dev/[slug]/+layout.svelte create mode 100644 src/renderer/src/routes/settings/dev/[slug]/+layout.ts create mode 100644 src/renderer/src/routes/settings/dev/[slug]/+page.svelte delete mode 100644 src/renderer/src/routes/settings/dev/add-app/+page.svelte delete mode 100644 src/renderer/src/routes/settings/dev/components/ReleasesCard.svelte delete mode 100644 src/renderer/src/routes/settings/dev/components/index.ts diff --git a/src/renderer/src/lib/components/AppDetailsPanel.svelte b/src/renderer/src/lib/components/AppDetailsPanel.svelte new file mode 100644 index 00000000..d54b14cf --- /dev/null +++ b/src/renderer/src/lib/components/AppDetailsPanel.svelte @@ -0,0 +1,34 @@ + + +
+
+ +

{title}

+
+ {#each buttons as button} + + {/each} +
diff --git a/src/renderer/src/lib/components/TopBar.svelte b/src/renderer/src/lib/components/TopBar.svelte new file mode 100644 index 00000000..feb01b61 --- /dev/null +++ b/src/renderer/src/lib/components/TopBar.svelte @@ -0,0 +1,3 @@ +
+ +
diff --git a/src/renderer/src/lib/components/index.ts b/src/renderer/src/lib/components/index.ts index c10bcf65..e24025a6 100644 --- a/src/renderer/src/lib/components/index.ts +++ b/src/renderer/src/lib/components/index.ts @@ -1,7 +1,9 @@ export { default as AddTypeModalFooter } from './AddTypeModalFooter.svelte'; +export { default as AppDetailsPanel } from './AppDetailsPanel.svelte'; export { default as Button } from './Button.svelte'; export { default as CenterProgressRadial } from './CenterProgressRadial.svelte'; export { default as IconButton } from './IconButton.svelte'; export { default as IconInput } from './IconInput.svelte'; export { default as Input } from './Input.svelte'; export { default as InputWithLabel } from './InputWithLabel.svelte'; +export { default as TopBar } from './TopBar.svelte'; diff --git a/src/renderer/src/lib/const/launcher.ts b/src/renderer/src/lib/const/launcher.ts index 9d18097a..34050dda 100644 --- a/src/renderer/src/lib/const/launcher.ts +++ b/src/renderer/src/lib/const/launcher.ts @@ -8,7 +8,6 @@ export const MODAL_ADD_NEW_HAPP_VERSION = 'modalAddNewHappVersion'; export const SELECTED_ICON_STYLE = 'fill-light-primary dark:fill-white'; export const DEV_PAGE = `${SETTINGS_SCREEN}/dev`; -export const ADD_APP_PAGE = 'add-app'; export const SEARCH_URL_QUERY = 'search'; export const PRESEARCH_URL_QUERY = 'presearch'; diff --git a/src/renderer/src/lib/const/menu.ts b/src/renderer/src/lib/const/menu.ts index 85905221..cf273913 100644 --- a/src/renderer/src/lib/const/menu.ts +++ b/src/renderer/src/lib/const/menu.ts @@ -1,4 +1,2 @@ export const SYSTEM_INFORMATION = 'systemInformation'; export const SYSTEM_SETTINGS = 'systemSettings'; - -export const VIEW = 'view'; diff --git a/src/renderer/src/lib/helpers/index.ts b/src/renderer/src/lib/helpers/index.ts index 1dc04a7f..e83c84de 100644 --- a/src/renderer/src/lib/helpers/index.ts +++ b/src/renderer/src/lib/helpers/index.ts @@ -1,2 +1,3 @@ export * from './display'; +export * from './navigation'; export * from './other'; diff --git a/src/renderer/src/lib/helpers/navigation.ts b/src/renderer/src/lib/helpers/navigation.ts new file mode 100644 index 00000000..31d4f46f --- /dev/null +++ b/src/renderer/src/lib/helpers/navigation.ts @@ -0,0 +1,38 @@ +import { get } from 'svelte/store'; + +import { goto } from '$app/navigation'; +import { page } from '$app/stores'; +import { SEARCH_URL_QUERY } from '$const'; +import { + ANIMATION_DURATION, + APPS_VIEW, + SEARCH_HEIGH, + WINDOW_SIZE, + WINDOW_SIZE_LARGE +} from '$shared/const'; +import type { MainScreenRoute } from '$shared/types'; + +export const setSearchInput = (event: CustomEvent) => { + const target = event.detail.target; + + goto(`?${SEARCH_URL_QUERY}=${target.value}`); +}; + +export const handleNavigationWithAnimationDelay = + (setInputExpandedFalse: () => void) => (destination: MainScreenRoute) => () => { + setInputExpandedFalse(); + setTimeout(() => { + const windowSize = + destination === APPS_VIEW + ? { width: WINDOW_SIZE, height: SEARCH_HEIGH } + : { width: WINDOW_SIZE_LARGE, height: WINDOW_SIZE }; + window.resizeTo(windowSize.width, windowSize.height); + goto(`/${destination}`); + }, ANIMATION_DURATION); + }; + +export const goBack = () => { + const { url } = get(page); + const lastSlashIndex = url.pathname.lastIndexOf('/'); + goto(url.pathname.substring(0, lastSlashIndex)); +}; diff --git a/src/renderer/src/lib/helpers/other.ts b/src/renderer/src/lib/helpers/other.ts index 9703251d..fa034a61 100644 --- a/src/renderer/src/lib/helpers/other.ts +++ b/src/renderer/src/lib/helpers/other.ts @@ -31,17 +31,6 @@ export const validateApp = (app: unknown): app is ExtendedAppInfo => export const uint8ArrayToURIComponent = (bytes: Uint8Array) => encodeURIComponent(encodeHashToBase64(bytes)); -export const getRawQueryParam = (url: string, param: string): string | null => { - const queryString = url.split('?')[1]; - if (!queryString) return null; - - return ( - queryString - .split('&') - .map((pair) => pair.split('=')) - .find(([key]) => key === param)?.[1] || null - ); -}; export const base64ToArrayBuffer = (base64: string) => { const binaryString = window.atob(base64); return new Uint8Array([...binaryString].map((char) => char.charCodeAt(0))); diff --git a/src/renderer/src/lib/icons/BackArrow.svelte b/src/renderer/src/lib/icons/BackArrow.svelte new file mode 100644 index 00000000..9e10ec82 --- /dev/null +++ b/src/renderer/src/lib/icons/BackArrow.svelte @@ -0,0 +1,9 @@ + + + diff --git a/src/renderer/src/lib/icons/Warning.svelte b/src/renderer/src/lib/icons/Warning.svelte index 79ef3933..c143096a 100644 --- a/src/renderer/src/lib/icons/Warning.svelte +++ b/src/renderer/src/lib/icons/Warning.svelte @@ -1,6 +1,6 @@ diff --git a/src/renderer/src/lib/icons/index.ts b/src/renderer/src/lib/icons/index.ts index 2f4d3912..66fdfcb9 100644 --- a/src/renderer/src/lib/icons/index.ts +++ b/src/renderer/src/lib/icons/index.ts @@ -1,5 +1,6 @@ export { default as ArrowLeft } from './ArrowLeft.svelte'; export { default as ArrowRight } from './ArrowRight.svelte'; +export { default as BackArrow } from './BackArrow.svelte'; export { default as Check } from './Check.svelte'; export { default as defaultIcon } from './default-icon.png?base64'; export { default as Gear } from './Gear.svelte'; diff --git a/src/renderer/src/lib/locale/en/common.json b/src/renderer/src/lib/locale/en/common.json index 88ee29db..4fe8042b 100644 --- a/src/renderer/src/lib/locale/en/common.json +++ b/src/renderer/src/lib/locale/en/common.json @@ -15,6 +15,7 @@ "confirmYourPassword": "Confirm your password", "country": "Country", "description": "Description", + "details": "Details", "discoverInstallAndManageYourApps": "Discover, install and manage your apps", "enterAppName": "Enter app name", "enterNetworkSeed": "Enter network seed", @@ -43,7 +44,7 @@ "open": "Open", "password": "password", "passwordPlaceholder": "Enter your password", - "passwordWarning": "Your password can not be reset, recovered or changed. Write it down and store it in a secure location.", + "passwordWarning": "Your password can not be reset, recovered or changed. Save it in your password manager or some other secure location.", "passwordsDontMatch": "Passwords don't match!", "region": "Region", "releases": "Releases", diff --git a/src/renderer/src/lib/modal/AddPublisher.svelte b/src/renderer/src/lib/modal/AddPublisher.svelte index 1d499479..04eca81c 100644 --- a/src/renderer/src/lib/modal/AddPublisher.svelte +++ b/src/renderer/src/lib/modal/AddPublisher.svelte @@ -4,7 +4,7 @@ import { goto } from '$app/navigation'; import { AddTypeModalFooter, IconInput } from '$components'; - import { ADD_APP_PAGE, DEV_PAGE } from '$const'; + import { DEV_PAGE } from '$const'; import { base64ToArrayBuffer } from '$helpers'; import { defaultIcon } from '$icons'; import { createAppQueries } from '$queries'; @@ -41,7 +41,7 @@ $publisherMutation.mutate(publisherData, { onSuccess: () => { modalStore.close(); - goto(`/${DEV_PAGE}/${ADD_APP_PAGE}`); + goto(`/${DEV_PAGE}`); } }); }} diff --git a/src/renderer/src/routes/(main)/+layout.svelte b/src/renderer/src/routes/(main)/+layout.svelte index 7231479e..7d321596 100644 --- a/src/renderer/src/routes/(main)/+layout.svelte +++ b/src/renderer/src/routes/(main)/+layout.svelte @@ -2,15 +2,86 @@ import { onMount } from 'svelte'; import { goto } from '$app/navigation'; - import { initializeAppPortSubscription } from '$helpers'; - import { trpc } from '$services'; - import { APPS_VIEW } from '$shared/const'; + import { page } from '$app/stores'; + import { IconButton, Input, TopBar } from '$components'; + import { SEARCH_URL_QUERY, SELECTED_ICON_STYLE } from '$const'; + import { + handleNavigationWithAnimationDelay, + initializeAppPortSubscription, + setSearchInput, + validateApp + } from '$helpers'; + import { Gear, Home, Rocket } from '$icons'; + import { i18n, trpc } from '$services'; + import { APP_STORE, APPS_VIEW } from '$shared/const'; + import { navigationStore } from '$stores'; const client = trpc(); const hideApp = client.hideApp.createMutation(); - const appPort = client.getAppPort.createQuery(); + const installedApps = client.getInstalledApps.createQuery(); + const openApp = client.openApp.createMutation(); + + const openSettings = client.openSettings.createMutation(); + + let inputExpanded = false; + + $: searchInput = $page.url.searchParams.get(SEARCH_URL_QUERY) || ''; + + $: filteredInstalledApps = + $installedApps?.data + ?.filter((app) => + app.appInfo.installed_app_id.toLowerCase().includes(searchInput.toLowerCase()) + ) + .filter(validateApp) ?? []; + + $: type = $page.url.pathname.includes(`/${APP_STORE}/`) + ? 'other' + : $page.url.pathname.includes(APP_STORE) + ? APP_STORE + : APPS_VIEW; + + $: autocomplete = + type === APPS_VIEW && filteredInstalledApps.length > 0 + ? filteredInstalledApps[0].appInfo.installed_app_id + : ''; + + $: if (type) inputExpanded = true; + + const handleNavigation = handleNavigationWithAnimationDelay(() => (inputExpanded = false)); + + onMount(() => { + return navigationStore.subscribe((value) => { + if (value !== null) { + handleNavigation(value)(); + navigationStore.set(null); + } + }); + }); + + const handlePress = (event: CustomEvent): void => { + if (!(event.detail instanceof KeyboardEvent)) return; + + const { key } = event.detail; + const hasApps = filteredInstalledApps.length > 0; + + if (key === 'Enter' && type === APPS_VIEW && hasApps && searchInput !== '') { + $openApp.mutate(filteredInstalledApps[0]); + return; + } + + if (key === 'Tab' && type === APPS_VIEW) { + event.detail.preventDefault(); + goto(`?${SEARCH_URL_QUERY}=${autocomplete}`); + return; + } + + if (key === 'Escape' && searchInput !== '') { + event.detail.stopPropagation(); + goto(`?${SEARCH_URL_QUERY}=`); + } + }; const handleEscapeKey = (event: KeyboardEvent): void => { if (event.key === 'Escape') { @@ -35,4 +106,46 @@ }); + + {#if type !== APP_STORE} + + {/if} + +
+ +
+ {#if type === APPS_VIEW} + + {:else} + + {/if} +
+
+ {#if type !== APPS_VIEW} + + + + {/if} + $openSettings.mutate(undefined)}> + + +
+ diff --git a/src/renderer/src/routes/(main)/app-store/+layout.svelte b/src/renderer/src/routes/(main)/app-store/+layout.svelte deleted file mode 100644 index b6887bc9..00000000 --- a/src/renderer/src/routes/(main)/app-store/+layout.svelte +++ /dev/null @@ -1,23 +0,0 @@ - - - - diff --git a/src/renderer/src/routes/(main)/app-store/+page.svelte b/src/renderer/src/routes/(main)/app-store/+page.svelte index ee44d502..91ec9baa 100644 --- a/src/renderer/src/routes/(main)/app-store/+page.svelte +++ b/src/renderer/src/routes/(main)/app-store/+page.svelte @@ -1,19 +1,26 @@
- {#each $appStoreHappsQuery.isSuccess ? $appStoreHappsQuery.data : [] as app} + {#each filteredAppStoreHapps as app} + import { page } from '$app/stores'; + import { IconButton, TopBar } from '$components'; + import { goBack, uint8ArrayToURIComponent } from '$helpers'; + import { BackArrow } from '$icons'; + import { createAppQueries } from '$queries'; + const { appStoreHappsQuery } = createAppQueries(); + + const slug: string = $page.params.slug; + const app = $appStoreHappsQuery.data?.find(({ id }) => uint8ArrayToURIComponent(id) === slug); + + + +
+ + {app?.title} +
+
+ +
+ +
diff --git a/src/renderer/src/routes/(main)/app-store/[slug]/+page.svelte b/src/renderer/src/routes/(main)/app-store/[slug]/+page.svelte index 42ed18e8..19edc403 100644 --- a/src/renderer/src/routes/(main)/app-store/[slug]/+page.svelte +++ b/src/renderer/src/routes/(main)/app-store/[slug]/+page.svelte @@ -1,6 +1,7 @@ {#if app} -
-

{app.title}

- {`${$i18n.t('releases')}:`} - {#if $appVersionsDetailsQuery?.data} - {#each $appVersionsDetailsQuery.data as versionEntry} -
-

{versionEntry.content.version}

-
- {/each} - {/if} -
+ {/if} -{#if $appVersionsDetailsQuery && $appVersionsDetailsQuery.isError} -
-
- {$appVersionsDetailsQuery.error?.message} +{#if $appVersionsDetailsQuery?.data} + {#each $appVersionsDetailsQuery.data as versionEntry} +
+

{versionEntry.content.version}

-
+ {/each} {/if} diff --git a/src/renderer/src/routes/(main)/app-store/components/AppCard.svelte b/src/renderer/src/routes/(main)/app-store/components/AppCard.svelte index 5add6424..ecd7e914 100644 --- a/src/renderer/src/routes/(main)/app-store/components/AppCard.svelte +++ b/src/renderer/src/routes/(main)/app-store/components/AppCard.svelte @@ -22,7 +22,7 @@ -
- {#each Object.entries(selectedApp.appInfo.cell_info) as [roleName, cellId]} - {@const cellIdResult = getCellId(cellId[0])} - {#if cellIdResult} -

- {roleName}: {encodeHashToBase64(cellIdResult[0])} -

- {/if} - {/each} -
-{:else} +

{$i18n.t('holochainVersion')}

{#if $holochainVersion.data} @@ -60,4 +15,4 @@

{/if}
-{/if} +
diff --git a/src/renderer/src/routes/settings/[slug]/+layout.ts b/src/renderer/src/routes/settings/[slug]/+layout.ts new file mode 100644 index 00000000..d43d0cd2 --- /dev/null +++ b/src/renderer/src/routes/settings/[slug]/+layout.ts @@ -0,0 +1 @@ +export const prerender = false; diff --git a/src/renderer/src/routes/settings/[slug]/+page.svelte b/src/renderer/src/routes/settings/[slug]/+page.svelte new file mode 100644 index 00000000..039ddbe8 --- /dev/null +++ b/src/renderer/src/routes/settings/[slug]/+page.svelte @@ -0,0 +1,54 @@ + + +{#if selectedApp} + +
+
+ +
+ {#each Object.entries(selectedApp.appInfo.cell_info) as [roleName, cellId]} + {@const cellIdResult = getCellId(cellId[0])} + {#if cellIdResult} +

+ {roleName}: {encodeHashToBase64(cellIdResult[0])} +

+ {/if} + {/each} +
+{:else} +
+

{$i18n.t(SYSTEM_SETTINGS)}

+
+{/if} diff --git a/src/renderer/src/routes/settings/components/DevMenu.svelte b/src/renderer/src/routes/settings/components/DevMenu.svelte index 26156130..ff4dab49 100644 --- a/src/renderer/src/routes/settings/components/DevMenu.svelte +++ b/src/renderer/src/routes/settings/components/DevMenu.svelte @@ -1,8 +1,8 @@ goto(`/${DEV_PAGE}/${ADD_APP_PAGE}`)} + onClick={() => goto(`/${DEV_PAGE}`)} isSelected >
diff --git a/src/renderer/src/routes/settings/components/RegularMenu.svelte b/src/renderer/src/routes/settings/components/RegularMenu.svelte index 43ad6bb4..dbc84682 100644 --- a/src/renderer/src/routes/settings/components/RegularMenu.svelte +++ b/src/renderer/src/routes/settings/components/RegularMenu.svelte @@ -1,7 +1,7 @@ -{#each systemViews as systemView} - selectView(systemView)} - isSelected={view === systemView || (!view && systemView === SYSTEM_INFORMATION)} - /> -{/each} + selectView('')} isSelected={!view} /> + selectView(SYSTEM_SETTINGS)} + isSelected={view === SYSTEM_SETTINGS} +/>
{#if $installedApps.isLoading}

{$i18n.t('loading')}

diff --git a/src/renderer/src/routes/settings/components/TopBar.svelte b/src/renderer/src/routes/settings/components/TopBar.svelte index ba05815c..9cd06054 100644 --- a/src/renderer/src/routes/settings/components/TopBar.svelte +++ b/src/renderer/src/routes/settings/components/TopBar.svelte @@ -5,7 +5,7 @@ import { goto } from '$app/navigation'; import { page } from '$app/stores'; import { IconButton } from '$components'; - import { ADD_APP_PAGE, DEV_PAGE, MODAL_ADD_PUBLISHER, SELECTED_ICON_STYLE } from '$const'; + import { DEV_PAGE, MODAL_ADD_PUBLISHER, SELECTED_ICON_STYLE } from '$const'; import { createModalParams } from '$helpers'; import { Gear, Home, Rocket, Upload } from '$icons'; import { createAppQueries } from '$queries'; @@ -37,7 +37,7 @@ if ($publishersQuery.data.length < 1) { return modalStore.trigger(modal); } - goto(isDevPage ? `/${SETTINGS_SCREEN}` : `${DEV_PAGE}/${ADD_APP_PAGE}`); + goto(isDevPage ? `/${SETTINGS_SCREEN}` : `${DEV_PAGE}`); }} > {#if isDevPage} diff --git a/src/renderer/src/routes/settings/dev/+page.svelte b/src/renderer/src/routes/settings/dev/+page.svelte index 159b1dd7..d0f8b55b 100644 --- a/src/renderer/src/routes/settings/dev/+page.svelte +++ b/src/renderer/src/routes/settings/dev/+page.svelte @@ -1,36 +1,89 @@ -
- {#if $appStoreMyHappsQuery.isSuccess} - {@const app = $appStoreMyHappsQuery.data.find( - (app) => uint8ArrayToURIComponent(app.id) === view - )} - {#if app} - {@const imageUrl = createImageUrl(app.icon)} -
- -

{app.title}

-
- - {/if} - {/if} -
+