Skip to content
Draft
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Changelog

## Unreleased
- Settings search

## v4.51.1
- iOS: fix App Store submission by packaging Inter as TTF fonts
Expand Down
19 changes: 19 additions & 0 deletions frontends/web/src/components/forms/search-input.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,22 @@
pointer-events: none;
width: 20px;
}

.clearButton {
align-items: center;
background: transparent;
border: none;
cursor: pointer;
display: flex;
flex: none;
height: 24px;
justify-content: center;
margin: auto 0;
padding: 0;
width: 24px;
}

.clearButton img {
height: 20px;
width: 20px;
}
60 changes: 54 additions & 6 deletions frontends/web/src/components/forms/search-input.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,61 @@
// SPDX-License-Identifier: Apache-2.0

import { forwardRef } from 'react';
import { Loupe } from '@/components/icon';
import { CloseXDark, CloseXWhite, Loupe } from '@/components/icon';
import { Input } from './input';
import type { TInputProps } from './input';
import styles from './search-input.module.css';

export const SearchInput = forwardRef<HTMLInputElement, TInputProps>((props, ref) => (
<Input ref={ref} type="text" {...props}>
<Loupe className={styles.searchIcon} />
</Input>
));
type TBaseProps = Omit<TInputProps, 'children' | 'type'>;

type TClearProps = TBaseProps & {
clearButtonLabel?: string;
onClear: () => void;
variant: 'clear';
};

type TSearchProps = TBaseProps & {
clearButtonLabel?: never;
onClear?: never;
variant?: 'search';
};

type TProps = TClearProps | TSearchProps;

export const SearchInput = forwardRef<HTMLInputElement, TProps>((props, ref) => {
if (props.variant === 'clear') {
const {
clearButtonLabel,
onClear,
variant: _variant,
...inputProps
} = props;

return (
<Input ref={ref} type="text" {...inputProps}>
{String(inputProps.value ?? '').trim().length > 0 ? (
<button
aria-label={clearButtonLabel}
className={styles.clearButton}
onClick={onClear}
type="button"
>
<CloseXDark className="show-in-lightmode" />
<CloseXWhite className="show-in-darkmode" />
</button>
) : null}
</Input>
);
}

const {
variant: _variant,
...inputProps
} = props;

return (
<Input ref={ref} type="text" {...inputProps}>
<Loupe className={styles.searchIcon} />
</Input>
);
});
3 changes: 3 additions & 0 deletions frontends/web/src/locales/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,9 @@
"title": "Manage notes"
},
"restart": "Please re-start the BitBoxApp for the changes to take effect.",
"search": {
"noResults": "No settings found"
},
"services": {
"title": "Services"
},
Expand Down
8 changes: 7 additions & 1 deletion frontends/web/src/routes/device/no-device-connected.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,15 @@ import { WithSettingsTabs } from '@/routes/settings/components/tabs';
import { ManageDeviceGuide } from './bitbox02/settings-guide';
import styles from './no-device-connected.module.css';

type TProps = TPagePropsWithSettingsTabs & {
hideSearch?: boolean;
};

export const NoDeviceConnected = ({
devices,
hideSearch,
hasAccounts,
}: TPagePropsWithSettingsTabs) => {
}: TProps) => {
const { t } = useTranslation();

return (
Expand All @@ -38,6 +43,7 @@ export const NoDeviceConnected = ({
<WithSettingsTabs
devices={devices}
hideMobileMenu
hideSearch={hideSearch}
hasAccounts={hasAccounts}
>
<div className={styles.noDevice}>
Expand Down
13 changes: 12 additions & 1 deletion frontends/web/src/routes/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,17 @@ export const AppRouter = ({ devices, devicesKey, accounts, activeAccounts }: TAp
<NoDeviceConnected
key="no-device-connected"
devices={devices}
hideSearch
hasAccounts={hasAccounts}
/>
</InjectParams>
);

const NoAccounts = (
<InjectParams>
<NoDeviceConnected
key="no-accounts"
devices={devices}
hasAccounts={hasAccounts}
/>
</InjectParams>
Expand Down Expand Up @@ -324,7 +335,7 @@ export const AppRouter = ({ devices, devicesKey, accounts, activeAccounts }: TAp
<Route path="about" element={AboutEl} />
<Route path="device-settings/:deviceID" element={Device} />
<Route path="no-device-connected" element={NoDevice} />
<Route path="no-accounts" element={NoDevice} />
<Route path="no-accounts" element={NoAccounts} />
<Route path="device-settings/passphrase/:deviceID" element={PassphraseEl} />
<Route path="device-settings/recovery-words/:deviceID" element={RecoveryWordsEl} />
<Route path="device-settings/bip85/:deviceID" element={Bip85El} />
Expand Down
28 changes: 25 additions & 3 deletions frontends/web/src/routes/settings/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ import { ContentWrapper } from '@/components/contentwrapper/contentwrapper';
import { GlobalBanners } from '@/components/banners';
import { FeedbackLink } from './components/about/feedback-link-setting';
import { SupportLink } from './components/about/support-link-setting';
import { SettingsContent, type TSettingsContentSection } from './components/settings-content';

type TProps = {
visibleItemIDs?: string[];
};

export const About = ({ devices, hasAccounts }: TPagePropsWithSettingsTabs) => {
const { t } = useTranslation();
Expand All @@ -34,9 +39,7 @@ export const About = ({ devices, hasAccounts }: TPagePropsWithSettingsTabs) => {
<View fullscreen={false}>
<ViewContent>
<WithSettingsTabs devices={devices} hideMobileMenu hasAccounts={hasAccounts}>
<AppVersion />
<FeedbackLink />
<SupportLink />
<AboutSettingsContent />
</WithSettingsTabs>
</ViewContent>
</View>
Expand All @@ -47,6 +50,25 @@ export const About = ({ devices, hasAccounts }: TPagePropsWithSettingsTabs) => {
);
};

export const AboutSettingsContent = ({ visibleItemIDs }: TProps) => {
const sections: TSettingsContentSection[] = [
{
id: 'about',
items: [
{ id: 'app-version', content: <AppVersion /> },
{ id: 'feedback', content: <FeedbackLink /> },
{ id: 'support', content: <SupportLink /> },
],
},
];

return (
<SettingsContent
sections={sections}
visibleItemIDs={visibleItemIDs}
/>
);
};

const AboutGuide = () => {
const { t } = useTranslation();
Expand Down
70 changes: 48 additions & 22 deletions frontends/web/src/routes/settings/advanced-settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Entry } from '@/components/guide/entry';
import { EnableAuthSetting } from './components/advanced-settings/enable-auth-setting';
import { ContentWrapper } from '@/components/contentwrapper/contentwrapper';
import { GlobalBanners } from '@/components/banners';
import { SettingsContent, type TSettingsContentSection } from './components/settings-content';

export type TProxyConfig = {
proxyAddress: string;
Expand All @@ -46,21 +47,13 @@ export type TConfig = {
frontend?: TFrontendConfig;
};

type TProps = {
devices: TPagePropsWithSettingsTabs['devices'];
visibleItemIDs?: string[];
};

export const AdvancedSettings = ({ devices, hasAccounts }: TPagePropsWithSettingsTabs) => {
const { t } = useTranslation();
const fetchedConfig = useLoad(getConfig) as TConfig;
const [config, setConfig] = useState<TConfig>();

const frontendConfig = config?.frontend;
const backendConfig = config?.backend;
const proxyConfig = config?.backend?.proxy;

useEffect(() => {
setConfig(fetchedConfig);
}, [fetchedConfig]);

const deviceIDs = Object.keys(devices);

return (
<GuideWrapper>
<GuidedContent>
Expand All @@ -83,15 +76,7 @@ export const AdvancedSettings = ({ devices, hasAccounts }: TPagePropsWithSetting
hideMobileMenu
hasAccounts={hasAccounts}
>
<EnableCustomFeesToggleSetting frontendConfig={frontendConfig} onChangeConfig={setConfig} />
<EnableCoinControlSetting frontendConfig={frontendConfig} onChangeConfig={setConfig} />
<EnableAuthSetting backendConfig={backendConfig} onChangeConfig={setConfig} />
<EnableTorProxySetting proxyConfig={proxyConfig} onChangeConfig={setConfig} />
<RestartInTestnetSetting onChangeConfig={setConfig} />
<CustomGapLimitSettings backendConfig={backendConfig} onChangeConfig={setConfig} />
<UnlockSoftwareKeystore deviceIDs={deviceIDs}/>
<ConnectFullNodeSetting />
<ExportLogSetting />
<AdvancedSettingsContent devices={devices} />
</WithSettingsTabs>
</ViewContent>
</View>
Expand All @@ -103,6 +88,47 @@ export const AdvancedSettings = ({ devices, hasAccounts }: TPagePropsWithSetting
);
};

export const AdvancedSettingsContent = ({
devices,
visibleItemIDs,
}: TProps) => {
const fetchedConfig = useLoad(getConfig) as TConfig;
const [config, setConfig] = useState<TConfig>();

const frontendConfig = config?.frontend;
const backendConfig = config?.backend;
const proxyConfig = config?.backend?.proxy;

useEffect(() => {
setConfig(fetchedConfig);
}, [fetchedConfig]);

const deviceIDs = Object.keys(devices);
const sections: TSettingsContentSection[] = [
{
id: 'advanced-settings',
items: [
{ id: 'custom-fees', content: <EnableCustomFeesToggleSetting frontendConfig={frontendConfig} onChangeConfig={setConfig} /> },
{ id: 'coin-control', content: <EnableCoinControlSetting frontendConfig={frontendConfig} onChangeConfig={setConfig} /> },
{ id: 'screen-lock', content: <EnableAuthSetting backendConfig={backendConfig} onChangeConfig={setConfig} /> },
{ id: 'tor-proxy', content: <EnableTorProxySetting proxyConfig={proxyConfig} onChangeConfig={setConfig} /> },
{ id: 'testnet-mode', content: <RestartInTestnetSetting onChangeConfig={setConfig} /> },
{ id: 'gap-limit', content: <CustomGapLimitSettings backendConfig={backendConfig} onChangeConfig={setConfig} /> },
{ id: 'test-wallet', content: <UnlockSoftwareKeystore deviceIDs={deviceIDs}/> },
{ id: 'full-node', content: <ConnectFullNodeSetting /> },
{ id: 'export-logs', content: <ExportLogSetting /> },
],
},
];

return (
<SettingsContent
sections={sections}
visibleItemIDs={visibleItemIDs}
/>
);
};


const AdvancedSettingsGuide = () => {
const { t } = useTranslation();
Expand Down
14 changes: 1 addition & 13 deletions frontends/web/src/routes/settings/bb02-settings.module.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
.section {
margin-bottom: var(--space-default)
}

.section h3 {
margin-bottom: var(--space-half)
}

.skeletonWrapper {
margin-bottom: var(--space-half);
}
Expand All @@ -15,8 +7,4 @@
.skeletonWrapper {
margin-bottom: 2px;
}

.withMobilePadding {
padding: 0 var(--space-half);
}
}
}
Loading