Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance app settings #217

Merged
merged 7 commits into from
Sep 11, 2024
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
5 changes: 3 additions & 2 deletions libs/appstore/src/appstore/appstore-app-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export class AppstoreAppClient {
allowlist: AppStoreAllowList,
denyList?: AppStoreDenyList,
): Promise<Entity<AppVersionEntry> | undefined> {
if (!allowlist) throw new Error('allowList undefined.');
// logic
// we need to check that there is a new version available and that the happ bundle hash is the same but the ui hash is different
const appVersionEntity = await this.appstoreZomeClient.getAppVersion(appVersionId);
Expand All @@ -125,14 +126,14 @@ export class AppstoreAppClient {
appVersionEntity.content.for_app,
);

const appEntryList = allowlist[encodeHashToBase64(appVersionEntity.content.for_app)];

const isUpdateCandidate = (entity: Entity<AppVersionEntry>) =>
entity.content.published_at > appVersionEntity.content.published_at &&
entity.content.bundle_hashes.happ_hash === appVersionEntity.content.bundle_hashes.happ_hash &&
entity.content.bundle_hashes.ui_hash !== appVersionEntity.content.bundle_hashes.ui_hash;

const appEntryList = allowlist[encodeHashToBase64(appVersionEntity.content.for_app)];
const isAllowedVersion = (entity: Entity<AppVersionEntry>) =>
!appEntryList ||
appEntryList.appVersions === 'all' ||
appEntryList.appVersions.includes(encodeHashToBase64(entity.action));

Expand Down
4 changes: 2 additions & 2 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
DEVHUB_APP_ID,
DISTRIBUTION_TYPE_DEFAULT_APP,
MAIN_WINDOW,
MIN_HEIGH,
MIN_HEIGHT,
SETTINGS_WINDOW,
WINDOW_SIZE,
} from '$shared/const';
Expand Down Expand Up @@ -942,7 +942,7 @@ const router = t.router({
}
await launchHolochain(password, LAIR_URL!);
IS_LAUNCHED = true;
PRIVILEDGED_LAUNCHER_WINDOWS[MAIN_WINDOW].setSize(WINDOW_SIZE, MIN_HEIGH, true);
PRIVILEDGED_LAUNCHER_WINDOWS[MAIN_WINDOW].setSize(WINDOW_SIZE, MIN_HEIGHT, true);
loadOrServe(PRIVILEDGED_LAUNCHER_WINDOWS[SETTINGS_WINDOW], { screen: SETTINGS_WINDOW });
}),
initializeDefaultAppPorts: t.procedure.query(async () => {
Expand Down
18 changes: 14 additions & 4 deletions src/main/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,14 @@ import serve from 'electron-serve';
import path from 'path';
import url from 'url';

import { MAIN_WINDOW, MIN_HEIGH, SETTINGS_SIZE, SETTINGS_WINDOW, WINDOW_SIZE } from '$shared/const';
import {
MAIN_WINDOW,
MIN_HEIGHT,
SETTINGS_HEIGHT,
SETTINGS_WIDTH,
SETTINGS_WINDOW,
WINDOW_SIZE,
} from '$shared/const';
import type { AdminWindow, ExtendedAppInfo } from '$shared/types';
import { LAUNCHER_ERROR } from '$shared/types';

Expand Down Expand Up @@ -53,19 +60,21 @@ const createAdminWindow = ({
optWidth,
frame = false,
icon,
height,
}: {
title: string;
optWidth?: number;
frame?: boolean;
icon?: Electron.NativeImage;
height?: number;
}) =>
new BrowserWindow({
frame: frame,
width: optWidth || WINDOW_SIZE,
minWidth: optWidth || WINDOW_SIZE,
height: WINDOW_SIZE,
height: height ? height : WINDOW_SIZE,
icon,
minHeight: MIN_HEIGH,
minHeight: MIN_HEIGHT,
title: title,
show: false,
webPreferences: {
Expand All @@ -85,7 +94,8 @@ export const setupAppWindows = (launcherEmitter: LauncherEmitter) => {
const settingsWindow = createAdminWindow({
title: 'Settings - Holochain Launcher',
frame: true,
optWidth: SETTINGS_SIZE,
optWidth: SETTINGS_WIDTH,
height: SETTINGS_HEIGHT,
icon: mainIcon,
});

Expand Down
4 changes: 2 additions & 2 deletions src/renderer/src/lib/helpers/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SEARCH_URL_QUERY } from '$const';
import {
ANIMATION_DURATION,
APPS_VIEW,
MIN_HEIGH,
MIN_HEIGHT,
WINDOW_SIZE,
WINDOW_SIZE_LARGE
} from '$shared/const';
Expand All @@ -20,7 +20,7 @@ export const setSearchInput = (event: CustomEvent) => {

const getWindowSize = (destination: MainScreenRoute) =>
destination === APPS_VIEW
? { width: WINDOW_SIZE, height: MIN_HEIGH }
? { width: WINDOW_SIZE, height: MIN_HEIGHT }
: { width: WINDOW_SIZE_LARGE, height: WINDOW_SIZE };

const resizeWindow = ({ width, height }: { width: number; height: number }) =>
Expand Down
32 changes: 25 additions & 7 deletions src/renderer/src/lib/helpers/other.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { encodeHashToBase64 } from '@holochain/client';
import type { ModalStore, ToastStore } from '@skeletonlabs/skeleton';
import { CellType, encodeHashToBase64, type CellInfo } from '@holochain/client';
import type { AppstoreAppClient, AppVersionEntry, Entity } from 'appstore-tools';
import localforage from 'localforage';

Expand All @@ -14,23 +13,42 @@ import {
ExtendedAppInfoSchema,
type InitializeAppPorts
} from '$shared/types';
import type { Modals } from '$types';
import { AppstoreFilterListsSchema } from '$types/happs';

import { createModalParams, showModalError } from './display';

export const getCellId = (cellInfo: unknown): CellId | undefined => {
const parsedCellInfo = CellInfoSchema.safeParse(cellInfo);

if (!parsedCellInfo.success || 'stem' in parsedCellInfo.data) {
if (!parsedCellInfo.success || CellType.Stem in parsedCellInfo.data) {
return undefined;
}

return 'provisioned' in parsedCellInfo.data
return CellType.Provisioned in parsedCellInfo.data
? parsedCellInfo.data.provisioned.cell_id
: parsedCellInfo.data.cloned.cell_id;
};

export function getCellNetworkSeed(cellInfo: any): string | undefined {
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.dna_modifiers.network_seed;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.dna_modifiers.network_seed;
}
return undefined;
}

export function getCellName(cellInfo: any): string | undefined {
if (CellType.Provisioned in cellInfo) {
return cellInfo.provisioned.name;
}
if (CellType.Cloned in cellInfo) {
return cellInfo.cloned.name;
}
if (CellType.Stem in cellInfo) {
return cellInfo.stem.name;
}
}

export const isNonEmptyString = (value: unknown): value is string =>
typeof value === 'string' && value.trim() !== '';

Expand Down
10 changes: 10 additions & 0 deletions src/renderer/src/lib/icons/TrashCan.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script lang="ts">
export let color: string | undefined;
export let width = 20;
</script>

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill={color ? color : ''} style={`width: ${width}px`}
><path
d="M9,3V4H4V6H5V19A2,2 0 0,0 7,21H17A2,2 0 0,0 19,19V6H20V4H15V3H9M7,6H17V19H7V6M9,8V17H11V8H9M13,8V17H15V8H13Z"
/></svg
>
17 changes: 14 additions & 3 deletions src/renderer/src/lib/locale/en/common.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"add": "Add",
"addApps": "Add Apps",
"addApp": "Add App",
"addNewRelease": "Add new release",
"addPublisher": "Add Publisher",
"addhApp": "Add a hApp",
Expand All @@ -25,14 +25,16 @@
"continue": "Continue",
"copiedToClipboard": "Copied to clipboard",
"copy": "Copy",
"copied": "Copied",
"country": "Country",
"description": "Description",
"details": "Details",
"developerTools": "Developer tools",
"developerTools": "Developer Tools",
"developerToolsAllow": "Developer tools allow you to",
"devhubInstalled": "DevHub installed",
"disabled": "Disabled",
"discoverInstallAndManageYourApps": "Discover, install and manage your apps",
"dnaHash": "DNA hash",
"downloadError": "Download Error",
"enabled": "Enabled",
"enterAppName": "Enter app name",
Expand All @@ -42,11 +44,13 @@
"factoryResetClick": "Click here to factory reset your Holochain Launcher",
"factoryResetConfirm": "Confirm Factory Reset",
"factoryResetError": "Factory Reset Failed",
"factoryResetHolochainLauncher": "Fully reset Holochain Launcher. This will delete all your apps alongside any associated data as well as your private keys.",
"factoryResetModalBody": "WARNING: This will delete all your apps alongside any data therein as well as your private keys.",
"fetchingAppData": "Fetching app data",
"generatingKeyRecoveryFile": "Generating key recovery file...",
"getStarted": "Get started",
"gettingAppBytes": "Getting app bytes",
"hide": "hide",
"hideUnverifiedApps": "Hide unverified apps",
"holochainLauncher": "Holochain Launcher",
"holochainVersion": "Holochain version",
Expand All @@ -64,7 +68,7 @@
"installingApp": "Installing app",
"installingAppStore": "Installing App Store...",
"installingDevHub": "Installing Dev Hub...",
"isUpdatedSuccessfully": " is updated successfully",
"updatedSuccessfully": " updated successfully",
"kando": "KanDo",
"keyManagement": "Key Management",
"launch": "Launch",
Expand All @@ -79,6 +83,8 @@
"networkSeedDescription": "The network seed is the string of characters used to generate a Holochain network. Anyone who has this network seed can join the network. The default network is public!",
"next": "Next",
"noAppsInstalled": "No apps installed.",
"noClonedCells": "No cloned cells",
"nothingToCopy": "Nothing to Copy",
"of": "of",
"oneLineDescription": "One line description",
"open": "Open",
Expand All @@ -91,6 +97,7 @@
"passwordsDontMatch": "Passwords don't match!",
"pollingForNewApps": "Polling for new apps...",
"pubKey": "Pub Key",
"publicKey": "Public Key",
"public": "Public",
"publish": "Publish",
"publishYourApp": "Publish your App",
Expand All @@ -99,6 +106,7 @@
"region": "Region",
"releases": "Releases",
"reset": "Reset",
"roleName": "Role Name",
"searchForApps": "Search for apps",
"setUpYourPublisherProfile": "Set up your publisher profile",
"setLauncherPassword": "Set Launcher Password",
Expand All @@ -107,11 +115,14 @@
"setupProgress": "Setup Progress",
"startingHolochain": "Starting Holochain...",
"startingLairKeystore": "Starting Lair Keystore...",
"show": "show",
"systemInformation": "System information",
"systemSettings": "System settings",
"theDeveloperToolkitSyncs": "The developer toolkit syncs with the app publishing network. Your local device will host files and potentially large amounts of data.",
"thisAppHasNotBeenVerifiedByTheHolochainFoundation": "This app has not been verified by the Holochain Foundation. Make sure you trust it before installing.",
"uninstall": "Uninstall",
"uninstallApp": "Uninstall App",
"uninstallAppAndRemoveAllData": "Uninstall this app and remove all associated data.",
"uninstallAppModalBody": "Are you sure you want to uninstall the app? This will delete all associated data.",
"updateAppDetails": "Update App Details",
"updateAvailable": "Update available",
Expand Down
21 changes: 14 additions & 7 deletions src/renderer/src/lib/queries/happs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
NO_PUBLISHERS_AVAILABLE_ERROR
} from '$shared/types';
import { type AppData, type AppWithAction, type PublishNewVersionData } from '$types';
import { HolochainFoundationList } from '$types/happs';

type ClientType = DevhubAppClient | AppstoreAppClient;

Expand Down Expand Up @@ -300,7 +301,7 @@ export const createPublishNewVersionMutation = (queryClient: QueryClient) => {

if (happHash !== previousHappHash)
throw new Error(
'happ sha256 does not match the happ sha256 of previous versions. Since coordinator zome updates are currently not supported, only app versions with the same happ file are allowed to be published under the same app entry'
'happ sha256 does not match the happ sha256 of previous versions. Since coordinator zome updates are currently not supported, only app versions with the same .happ file are allowed to be published in subsequent releases for the same app.'
);

const hashes: BundleHashes = {
Expand Down Expand Up @@ -358,20 +359,26 @@ export const createCheckForAppUiUpdatesQuery =
return createQuery({
queryKey: [CHECK_FOR_APP_UI_UPDATES_QUERY_KEY, appVersionActionHashes],
queryFn: async () => {
console.log("Checking for UI updates...")
const appStoreClient = getAppStoreClientOrThrow();
const distinctVersionHashes = appVersionActionHashes;
const filterLists = await fetchFilterLists(appStoreClient, isDev);
const updates = await Promise.all(
distinctVersionHashes.map(async (hash) => {
const maybeUpdate = await appStoreClient.checkForUiUpdate(
decodeHashFromBase64(hash!),
filterLists.allowlists[hash!],
filterLists.denylist
);
let maybeUpdate;
try {
maybeUpdate = await appStoreClient.checkForUiUpdate(
decodeHashFromBase64(hash!),
filterLists.allowlists[HolochainFoundationList.value],
filterLists.denylist
);
} catch (e) {
console.error("Failed to check for UI update: ", e);
}
return maybeUpdate ? { [hash]: maybeUpdate } : null;
})
);

console.log("Got updates: ", updates);
return updates.reduce((acc, update) => (update ? { ...acc, ...update } : acc), {});
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
export let onClick = () => {};
export let initials: string = '';
export let src: string | undefined = undefined;
export let border: string = 'border-4 border-white border-opacity-20';
export let border: string = 'border-4 border-white border-opacity-20 hover:border-opacity-30';
export let fontSize: number | undefined = undefined;
export let fill: string = 'fill-white';
export let background: string = 'bg-transparent';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
initials="+"
onClick={handleNavigationWithAnimationDelay()(APP_STORE)}
>
<span class="pt-2 text-xs opacity-50">{$i18n.t('addApps')}</span>
<span class="pt-2 text-xs opacity-50">{$i18n.t('addApp')}</span>
</BaseButton>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions src/renderer/src/routes/settings/(menu)/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<div class="flex flex-1 overflow-hidden bg-light-background bg-fixed dark:bg-app-dark-gradient">
<div
class="w-[35%] overflow-y-auto bg-light-background bg-fixed shadow-3xl dark:bg-app-dark-gradient"
class="w-[35%] max-w-72 overflow-y-auto bg-light-background bg-fixed shadow-3xl dark:bg-app-dark-gradient"
>
<div class="space-y-4 p-4">
<div class="flex flex-col space-y-1">
Expand All @@ -21,7 +21,7 @@
</div>
</div>
</div>
<div class="min-h-[calc(100vh-70px)] flex-1 overflow-y-auto">
<div class="min-h-[calc(100vh-70px)] flex flex-col flex-1 overflow-y-auto">
<slot />
</div>
</div>
2 changes: 1 addition & 1 deletion src/renderer/src/routes/settings/(menu)/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
const defaultHolochainVersion = client.defaultHolochainVersion.createQuery();
</script>

<div class="p-4">
<div class="p-5">
<div>
<h3 class="h3">{$i18n.t('holochainVersion')}</h3>
{#if $defaultHolochainVersion.data}
Expand Down
Loading