mirror of
https://github.com/PrimalHQ/primal-web-app.git
synced 2024-10-01 17:31:13 +00:00
Add restore feeds button
This commit is contained in:
parent
c9bc34433b
commit
ed567bb9f7
68
src/components/ConfirmModal/ConfirmModal.module.scss
Normal file
68
src/components/ConfirmModal/ConfirmModal.module.scss
Normal file
@ -0,0 +1,68 @@
|
||||
|
||||
|
||||
.feedsRestoreModal {
|
||||
position: fixed;
|
||||
width: 420px;
|
||||
color: var(--text-secondary);
|
||||
background-color: var(--background-site);
|
||||
background: linear-gradient(var(--background-site),
|
||||
var(--background-site)) padding-box,
|
||||
var(--brand-gradient) border-box;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 22px;
|
||||
|
||||
.feedConfirmationTitle {
|
||||
font-weight: 800;
|
||||
font-size: 18px;
|
||||
line-height: 18px;
|
||||
color: var(--text-secondary);
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.feedConfirmationDescription {
|
||||
color: var(--text-secondary);
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.feedConfirmationActions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.feedRestoreConfirm {
|
||||
background: var(--brand-gradient-vertical);
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 700;
|
||||
padding: 8px;
|
||||
margin: 0px;
|
||||
max-width: 40%;
|
||||
}
|
||||
|
||||
.feedRestoreAbort {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
font-weight: 700;
|
||||
color: var(--text-secondary);
|
||||
background-color: var(--background-site);
|
||||
background: linear-gradient(var(--background-site),
|
||||
var(--background-site)) padding-box,
|
||||
var(--brand-gradient) border-box;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
margin: 0;
|
||||
max-width: 40%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
59
src/components/ConfirmModal/ConfirmModal.tsx
Normal file
59
src/components/ConfirmModal/ConfirmModal.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import { useIntl } from '@cookbook/solid-intl';
|
||||
import { Component, createEffect, createSignal, For } from 'solid-js';
|
||||
import { useAccountContext } from '../../contexts/AccountContext';
|
||||
import { useSettingsContext } from '../../contexts/SettingsContext';
|
||||
import { zapNote } from '../../lib/zap';
|
||||
import { userName } from '../../stores/profile';
|
||||
import { toastZapFail, zapCustomOption } from '../../translations';
|
||||
import { PrimalNote } from '../../types/primal';
|
||||
import { debounce } from '../../utils';
|
||||
import Modal from '../Modal/Modal';
|
||||
import { useToastContext } from '../Toaster/Toaster';
|
||||
|
||||
import { confirmDefaults as t } from '../../translations';
|
||||
|
||||
import styles from './ConfirmModal.module.scss';
|
||||
|
||||
const ConfirmModal: Component<{
|
||||
open?: boolean,
|
||||
title?: string,
|
||||
description?: string,
|
||||
confirmLabel?: string,
|
||||
abortLablel?: string
|
||||
onConfirm: () => void,
|
||||
onAbort: () => void,
|
||||
}> = (props) => {
|
||||
|
||||
const intl = useIntl();
|
||||
|
||||
return (
|
||||
<Modal open={props.open}>
|
||||
<div class={styles.feedsRestoreModal}>
|
||||
<div class={styles.feedConfirmationTitle}>
|
||||
{props.title || intl.formatMessage(t.title)}
|
||||
</div>
|
||||
<div class={styles.feedConfirmationDescription}>
|
||||
{props.description}
|
||||
</div>
|
||||
<div class={styles.feedConfirmationActions}>
|
||||
<button
|
||||
class={styles.feedRestoreConfirm}
|
||||
onClick={props.onConfirm}
|
||||
>
|
||||
{props.confirmLabel || intl.formatMessage(t.confirm)}
|
||||
</button>
|
||||
|
||||
<button
|
||||
class={styles.feedRestoreAbort}
|
||||
onClick={props.onAbort}
|
||||
>
|
||||
{props.abortLablel || intl.formatMessage(t.abort)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default ConfirmModal;
|
@ -33,6 +33,7 @@ import { getDefaultSettings, getSettings, sendSettings } from "../lib/settings";
|
||||
import { APP_ID } from "../App";
|
||||
import { useIntl } from "@cookbook/solid-intl";
|
||||
import { hexToNpub } from "../lib/keys";
|
||||
import { settings as t } from "../translations";
|
||||
|
||||
export type SettingsContextStore = {
|
||||
locale: string,
|
||||
@ -55,6 +56,7 @@ export type SettingsContextStore = {
|
||||
setDefaultZapAmount: (amount: number) => void,
|
||||
setZapOptions: (amount:number, index: number) => void,
|
||||
updateNotificationSettings: (key: string, value: boolean, temp?: boolean) => void,
|
||||
restoreDefaultFeeds: () => void,
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +177,54 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
!temp && saveSettings();
|
||||
};
|
||||
|
||||
const restoreDefaultFeeds = () => {
|
||||
|
||||
const subid = `restore_default_${APP_ID}`;
|
||||
|
||||
const unsub = subscribeTo(subid, async (type, subId, content) => {
|
||||
|
||||
if (type === 'EVENT' && content?.content) {
|
||||
try {
|
||||
const settings = JSON.parse(content?.content);
|
||||
|
||||
let feeds = settings.feeds as PrimalFeed[];
|
||||
|
||||
if (account?.hasPublicKey()) {
|
||||
feeds.unshift({
|
||||
name: feedLabel,
|
||||
hex: account?.publicKey,
|
||||
npub: hexToNpub(account?.publicKey),
|
||||
});
|
||||
}
|
||||
|
||||
updateStore('availableFeeds',
|
||||
() => replaceAvailableFeeds(account?.publicKey, feeds),
|
||||
);
|
||||
|
||||
updateStore('defaultFeed', () => store.availableFeeds[0]);
|
||||
|
||||
saveSettings();
|
||||
}
|
||||
catch (e) {
|
||||
console.log('Error parsing settings response: ', e);
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'NOTICE') {
|
||||
toaster?.sendWarning(intl.formatMessage({
|
||||
id: 'settings.loadFail',
|
||||
defaultMessage: 'Failed to load settings. Will be using local settings.',
|
||||
description: 'Toast message after settings have failed to be loaded from the server',
|
||||
}));
|
||||
}
|
||||
|
||||
unsub();
|
||||
return;
|
||||
});
|
||||
|
||||
getDefaultSettings(subid)
|
||||
};
|
||||
|
||||
const saveSettings = () => {
|
||||
const settings = {
|
||||
theme: store.theme,
|
||||
@ -215,14 +265,6 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
const feeds = settings.feeds as PrimalFeed[];
|
||||
const notificationSettings = settings.notifications as Record<string, boolean>;
|
||||
|
||||
// const availableTopics = store.availableFeeds.map(f => f.hex);
|
||||
|
||||
// const updatedFeeds = feeds.reduce((acc, feed) => {
|
||||
// return availableTopics.includes(feed.hex) ?
|
||||
// acc :
|
||||
// [ ...acc, feed ];
|
||||
// }, store.availableFeeds)
|
||||
|
||||
updateStore('availableFeeds',
|
||||
() => replaceAvailableFeeds(account?.publicKey, feeds),
|
||||
);
|
||||
@ -342,11 +384,7 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
|
||||
// This is here as to not trigger the effect
|
||||
// TODO Solve this.
|
||||
const feedLabel = intl.formatMessage({
|
||||
id: 'feeds.latestFollowing',
|
||||
defaultMessage: 'Latest, following',
|
||||
description: 'Label for the `latest;following` (active user\'s) feed',
|
||||
});
|
||||
const feedLabel = intl.formatMessage(t.feedLatest);
|
||||
|
||||
|
||||
// Initial setup for a user with a public key
|
||||
@ -426,6 +464,7 @@ export const SettingsProvider = (props: { children: ContextChildren }) => {
|
||||
renameAvailableFeed,
|
||||
saveSettings,
|
||||
loadSettings,
|
||||
restoreDefaultFeeds,
|
||||
setDefaultZapAmount,
|
||||
setZapOptions,
|
||||
updateNotificationSettings,
|
||||
|
@ -35,6 +35,33 @@
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.feedCaption {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-top: -10px;
|
||||
.settingsCaption {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.restoreFeedsButton {
|
||||
background-color: var(--background-site);
|
||||
color: var(--text-tertiary);
|
||||
width: auto;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding-block: 10px;
|
||||
padding-inline: 10px;
|
||||
|
||||
&:hover {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.devider {
|
||||
width: 100%;
|
||||
border-bottom: solid 1px var(--subtile-devider);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Component } from 'solid-js';
|
||||
import { Component, createSignal, Show } from 'solid-js';
|
||||
import Branding from '../components/Branding/Branding';
|
||||
import styles from './Settings.module.scss';
|
||||
|
||||
@ -10,10 +10,21 @@ import SettingsZap from '../components/SettingsZap/SettingsZap';
|
||||
import Search from '../components/Search/Search';
|
||||
import SettingsNotifications from '../components/SettingsNotifications/SettingsNotifications';
|
||||
import { settings as t } from '../translations';
|
||||
import { useSettingsContext } from '../contexts/SettingsContext';
|
||||
import Modal from '../components/Modal/Modal';
|
||||
import ConfirmModal from '../components/ConfirmModal/ConfirmModal';
|
||||
|
||||
const Settings: Component = () => {
|
||||
|
||||
const intl = useIntl();
|
||||
const settings = useSettingsContext();
|
||||
|
||||
const [isRestoringFeeds, setIsRestoringFeeds] = createSignal(false);
|
||||
|
||||
const onRestoreFeeds = () => {
|
||||
settings?.actions.restoreDefaultFeeds();
|
||||
setIsRestoringFeeds(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<div class={styles.settingsContainer}>
|
||||
@ -40,10 +51,27 @@ const Settings: Component = () => {
|
||||
|
||||
<div class={styles.devider}></div>
|
||||
|
||||
<div class={styles.feedCaption}>
|
||||
<div class={styles.settingsCaption}>
|
||||
{intl.formatMessage(t.feeds)}
|
||||
</div>
|
||||
|
||||
<button
|
||||
class={styles.restoreFeedsButton}
|
||||
onClick={() => setIsRestoringFeeds(true)}
|
||||
>
|
||||
{intl.formatMessage(t.feedsRestore)}
|
||||
</button>
|
||||
|
||||
<ConfirmModal
|
||||
open={isRestoringFeeds()}
|
||||
description={intl.formatMessage(t.feedsRestoreConfirm)}
|
||||
onConfirm={onRestoreFeeds}
|
||||
onAbort={() => setIsRestoringFeeds(false)}
|
||||
></ConfirmModal>
|
||||
</div>
|
||||
|
||||
|
||||
<div class={styles.feedSettings}>
|
||||
<FeedSorter />
|
||||
</div>
|
||||
|
@ -119,6 +119,24 @@ export const downloads = {
|
||||
},
|
||||
};
|
||||
|
||||
export const confirmDefaults = {
|
||||
title: {
|
||||
id: 'confirm.title',
|
||||
defaultMessage: 'Are you sure?',
|
||||
description: 'Default title of the confirmation dialog',
|
||||
},
|
||||
confirm: {
|
||||
id: 'confirm.yes',
|
||||
defaultMessage: 'Yes',
|
||||
description: 'Default label form positive response to the confirmation dialog',
|
||||
},
|
||||
abort: {
|
||||
id: 'confirm.no',
|
||||
defaultMessage: 'No',
|
||||
description: 'Default label form negative response to the confirmation dialog',
|
||||
},
|
||||
};
|
||||
|
||||
export const exploreSidebarCaption = {
|
||||
id: 'explore.sidebar.caption',
|
||||
defaultMessage: 'trending users',
|
||||
@ -616,6 +634,21 @@ export const settings = {
|
||||
defaultMessage: 'Home page feeds',
|
||||
description: 'Title of the feeds section on the settings page',
|
||||
},
|
||||
feedsRestore: {
|
||||
id: 'settings.feedsRestore',
|
||||
defaultMessage: 'Reset to default feeds',
|
||||
description: 'Label for the button for restoring default feeds to the feeds list',
|
||||
},
|
||||
feedsRestoreConfirm: {
|
||||
id: 'settings.feedsRestoreConfirm',
|
||||
defaultMessage: 'Restoring default feeds will erase all your custom feed settings',
|
||||
description: 'Label explaining the impact of restoring default feeds',
|
||||
},
|
||||
feedLatest: {
|
||||
id: 'feeds.latestFollowing',
|
||||
defaultMessage: 'Latest',
|
||||
description: 'Label for the `latest;following` (active user\'s) feed',
|
||||
},
|
||||
zaps: {
|
||||
id: 'settings.sections.zaps',
|
||||
defaultMessage: 'Zaps',
|
||||
|
Loading…
Reference in New Issue
Block a user