Skip to content

Commit

Permalink
make app settings use query store
Browse files Browse the repository at this point in the history
  • Loading branch information
hzrd149 committed Oct 11, 2024
1 parent 60b61e9 commit bb855a2
Show file tree
Hide file tree
Showing 27 changed files with 274 additions and 253 deletions.
37 changes: 3 additions & 34 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/classes/accounts/account.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { AppSettings } from "../../services/settings/migrations";
import { AppSettings } from "../../helpers/app-settings";
import { Nip07Interface } from "applesauce-signer";

Check failure on line 2 in src/classes/accounts/account.ts

View workflow job for this annotation

GitHub Actions / deploy

Cannot find module 'applesauce-signer' or its corresponding type declarations.

export class Account {
readonly type: string = "unknown";
pubkey: string;
localSettings?: AppSettings;
localSettings?: Partial<AppSettings>;

protected _signer?: Nip07Interface | undefined;
public get signer(): Nip07Interface | undefined {
Expand Down
4 changes: 2 additions & 2 deletions src/components/embed-event/event-types/embedded-note.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import { TrustProvider } from "../../../providers/local/trust-provider";
import { NoteLink } from "../../note/note-link";
Expand All @@ -17,9 +16,10 @@ import HoverLinkOverlay from "../../hover-link-overlay";
import singleEventService from "../../../services/single-event";
import relayHintService from "../../../services/event-relay-hint";
import localSettings from "../../../services/local-settings";
import useAppSettings from "../../../hooks/use-app-settings";

export default function EmbeddedNote({ event, ...props }: Omit<CardProps, "children"> & { event: NostrEvent }) {
const { showSignatureVerification } = useSubject(appSettings);
const { showSignatureVerification } = useAppSettings();
const enableDrawer = useSubject(localSettings.enableNoteThreadDrawer);
const navigate = enableDrawer ? useNavigateInDrawer() : useNavigate();
const to = `/n/${relayHintService.getSharableEventAddress(event)}`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { Link as RouterLink } from "react-router-dom";
import { NostrEvent } from "../../../types/nostr-event";
import UserAvatarLink from "../../user/user-avatar-link";
import UserLink from "../../user/user-link";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import { TrustProvider } from "../../../providers/local/trust-provider";
import Timestamp from "../../timestamp";
Expand All @@ -17,13 +15,14 @@ import { getTorrentTitle } from "../../../helpers/nostr/torrents";
import { useNavigateInDrawer } from "../../../providers/drawer-sub-view-provider";
import { MouseEventHandler, useCallback } from "react";
import { nip19 } from "nostr-tools";
import useAppSettings from "../../../hooks/use-app-settings";

export default function EmbeddedTorrentComment({
comment,
...props
}: Omit<CardProps, "children"> & { comment: NostrEvent }) {
const navigate = useNavigateInDrawer();
const { showSignatureVerification } = useSubject(appSettings);
const { showSignatureVerification } = useAppSettings();
const refs = getThreadReferences(comment);
const torrent = useSingleEvent(refs.root?.e?.id, refs.root?.e?.relays);
const linkToTorrent = refs.root?.e && `/torrents/${nip19.neventEncode(refs.root.e)}`;
Expand Down
6 changes: 4 additions & 2 deletions src/components/event-zap-modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ import { EmbedProps } from "../embed-event";
import userMailboxesService from "../../services/user-mailboxes";
import InputStep from "./input-step";
import lnurlMetadataService from "../../services/lnurl-metadata";
import userMetadataService from "../../services/user-metadata";
import signingService from "../../services/signing";
import accountService from "../../services/account";
import PayStep from "./pay-step";
import { getInvoiceFromCallbackUrl } from "../../helpers/lnurl";
import UserLink from "../user/user-link";
import relayHintService from "../../services/event-relay-hint";
import { queryStore } from "../../services/event-store";
import { getValue } from "applesauce-core/observable";

export type PayRequest = { invoice?: string; pubkey: string; error?: any };

Expand All @@ -38,7 +39,8 @@ async function getPayRequestForPubkey(
comment?: string,
additionalRelays?: Iterable<string>,
): Promise<PayRequest> {
const metadata = userMetadataService.getSubject(pubkey).value;
const metadata = await getValue(queryStore.profile(pubkey));
if (!metadata) throw new Error("Cant find user metadata");
const address = metadata?.lud16 || metadata?.lud06;
if (!address) throw new Error("User missing lightning address");
const lnurlMetadata = await lnurlMetadataService.requestMetadata(address);
Expand Down
9 changes: 6 additions & 3 deletions src/components/event-zap-modal/pay-step.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import UserLink from "../user/user-link";
import { ChevronDownIcon, ChevronUpIcon, CheckIcon, ErrorIcon, LightningIcon } from "../icons";
import { InvoiceModalContent } from "../invoice-modal";
import { PropsWithChildren, useEffect, useState } from "react";
import appSettings from "../../services/settings/app-settings";
import useAppSettings from "../../hooks/use-app-settings";

function UserCard({ children, pubkey }: PropsWithChildren & { pubkey: string }) {
return (
Expand Down Expand Up @@ -79,6 +79,7 @@ function ErrorCard({ pubkey, error }: { pubkey: string; error: any }) {

export default function PayStep({ callbacks, onComplete }: { callbacks: PayRequest[]; onComplete: () => void }) {
const [paid, setPaid] = useState<string[]>([]);
const { autoPayWithWebLN } = useAppSettings();

const [payingAll, setPayingAll] = useState(false);
const payAllWithWebLN = async () => {
Expand All @@ -99,14 +100,16 @@ export default function PayStep({ callbacks, onComplete }: { callbacks: PayReque
};

useEffect(() => {
if (!callbacks.filter((p) => !!p.invoice).some(({ pubkey }) => !paid.includes(pubkey))) {
const withInvoice = callbacks.filter((p) => !!p.invoice);
const hasUnpaid = withInvoice.some(({ pubkey }) => !paid.includes(pubkey));
if (withInvoice.length > 0 && !hasUnpaid) {
onComplete();
}
}, [paid]);

// if autoPayWithWebLN is enabled, try to pay all immediately
useMount(() => {
if (appSettings.value.autoPayWithWebLN) {
if (autoPayWithWebLN) {
payAllWithWebLN();
}
});
Expand Down
13 changes: 9 additions & 4 deletions src/components/external-embeds/types/music.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { CSSProperties } from "react";
import { Box, useColorMode } from "@chakra-ui/react";
import { EmbedEventPointer } from "../../embed-event";
import appSettings from "../../../services/settings/app-settings";
import { STEMSTR_RELAY } from "../../../helpers/nostr/stemstr";
import ExpandableEmbed from "../expandable-embed";
import useAppSettings from "../../../hooks/use-app-settings";

const setZIndex: CSSProperties = { zIndex: 1, position: "relative" };

Expand Down Expand Up @@ -137,8 +137,8 @@ export function renderStemstrUrl(match: URL) {
return <EmbedEventPointer pointer={{ type: "nevent", data: { id, relays: [STEMSTR_RELAY] } }} />;
}

export function renderSoundCloudUrl(match: URL) {
if (match.hostname !== "soundcloud.com" || match.pathname.split("/").length !== 3) return null;
function SoundCloudEmbed({ match }: { match: URL }) {
const { primaryColor } = useAppSettings();

return (
<iframe
Expand All @@ -150,9 +150,14 @@ export function renderSoundCloudUrl(match: URL) {
src={`https://w.soundcloud.com/player/?url=${encodeURIComponent(
match.protocol + match.host + match.pathname,
)}&color=${encodeURIComponent(
"#" + appSettings.value.primaryColor || "ff5500",
"#" + primaryColor || "ff5500",
)}&auto_play=false&hide_related=false&show_comments=true&show_user=true&show_reposts=false&show_teaser=true`}
style={setZIndex}
></iframe>
);
}
export function renderSoundCloudUrl(match: URL) {
if (match.hostname !== "soundcloud.com" || match.pathname.split("/").length !== 3) return null;

return <SoundCloudEmbed match={match} />;
}
14 changes: 9 additions & 5 deletions src/components/external-embeds/types/reddit.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { replaceDomain } from "../../../helpers/url";
import appSettings from "../../../services/settings/app-settings";
import useAppSettings from "../../../hooks/use-app-settings";
import { renderGenericUrl } from "./common";

// copied from https://github.com/SimonBrazell/privacy-redirect/blob/master/src/assets/javascripts/helpers/reddit.js
Expand All @@ -13,13 +13,17 @@ const REDDIT_DOMAINS = [
"old.reddit.com",
];

function RedditLink({ url }: { url: URL }) {
const { redditRedirect } = useAppSettings();
const fixed = redditRedirect ? replaceDomain(url, redditRedirect) : url;

return renderGenericUrl(fixed);
}

const bypassPaths = /\/(gallery\/poll\/rpan\/settings\/topics)/;
export function renderRedditUrl(match: URL) {
if (!REDDIT_DOMAINS.includes(match.hostname)) return null;
if (match.pathname.match(bypassPaths)) return null;

const { redditRedirect } = appSettings.value;
const fixed = redditRedirect ? replaceDomain(match, redditRedirect) : match;

return renderGenericUrl(fixed);
return <RedditLink url={match} />;
}
12 changes: 8 additions & 4 deletions src/components/external-embeds/types/twitter.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import { replaceDomain } from "../../../helpers/url";
import appSettings from "../../../services/settings/app-settings";
import useAppSettings from "../../../hooks/use-app-settings";
import { renderOpenGraphUrl } from "./common";

// copied from https://github.com/SimonBrazell/privacy-redirect/blob/master/src/assets/javascripts/helpers/twitter.js
export const TWITTER_DOMAINS = ["x.com", "twitter.com", "www.twitter.com", "mobile.twitter.com", "pbs.twimg.com"];

function TwitterLink({ url, isLineEnd }: { url: URL; isLineEnd?: boolean }) {
const { twitterRedirect } = useAppSettings();
if (twitterRedirect) return renderOpenGraphUrl(replaceDomain(url, twitterRedirect), !!isLineEnd);
else return renderOpenGraphUrl(url, !!isLineEnd);
}

export function renderTwitterUrl(match: URL, isLineEnd: boolean) {
if (!TWITTER_DOMAINS.includes(match.hostname)) return null;

const { twitterRedirect } = appSettings.value;
if (twitterRedirect) return renderOpenGraphUrl(replaceDomain(match, twitterRedirect), isLineEnd);
else return renderOpenGraphUrl(match, isLineEnd);
return <TwitterLink url={match} isLineEnd={isLineEnd} />;
}
46 changes: 28 additions & 18 deletions src/components/external-embeds/types/youtube.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AspectRatio } from "@chakra-ui/react";
import appSettings from "../../../services/settings/app-settings";
import ExpandableEmbed from "../expandable-embed";
import useAppSettings from "../../../hooks/use-app-settings";

// copied from https://github.com/SimonBrazell/privacy-redirect/blob/master/src/assets/javascripts/helpers/youtube.js
export const YOUTUBE_DOMAINS = [
Expand All @@ -15,20 +15,15 @@ export const YOUTUBE_DOMAINS = [
"music.youtube.com",
];

export function renderYoutubePlaylistURL(match: URL) {
if (!YOUTUBE_DOMAINS.includes(match.hostname)) return null;
if (!match.pathname.startsWith("/playlist")) return null;

const { youtubeRedirect } = appSettings.value;

const listId = match.searchParams.get("list");
if (!listId) return null;
function YoutubePlaylistEmbed({ url }: { url: URL }) {
const { youtubeRedirect } = useAppSettings();
const listId = url.searchParams.get("list")!;

const embedUrl = new URL(`embed/videoseries`, youtubeRedirect || "https://www.youtube-nocookie.com");
embedUrl.searchParams.set("list", listId);

return (
<ExpandableEmbed label="Youtube Playlist" url={match}>
<ExpandableEmbed label="Youtube Playlist" url={url}>
<AspectRatio ratio={560 / 315} maxWidth="40rem" zIndex={1} position="relative">
<iframe
src={embedUrl.toString()}
Expand All @@ -42,20 +37,26 @@ export function renderYoutubePlaylistURL(match: URL) {
);
}

export function renderYoutubeVideoURL(match: URL) {
export function renderYoutubePlaylistURL(match: URL) {
if (!YOUTUBE_DOMAINS.includes(match.hostname)) return null;
if (match.pathname.startsWith("/live")) return null;
if (!match.pathname.startsWith("/playlist")) return null;

const { youtubeRedirect } = appSettings.value;
const listId = match.searchParams.get("list");
if (!listId) return null;

var videoId = match.searchParams.get("v");
if (match.hostname === "youtu.be") videoId = match.pathname.split("/")[1];
return <YoutubePlaylistEmbed url={match} />;
}

function YoutubeVideoEmbed({ url }: { url: URL }) {
const { youtubeRedirect } = useAppSettings();
var videoId = url.searchParams.get("v");
if (url.hostname === "youtu.be") videoId = url.pathname.split("/")[1];
if (!videoId) return null;

const embedUrl = new URL(`/embed/${videoId}`, youtubeRedirect || "https://www.youtube-nocookie.com");

return (
<ExpandableEmbed label="Youtube" url={match}>
<ExpandableEmbed label="Youtube" url={url}>
<AspectRatio ratio={16 / 10} maxWidth="40rem" zIndex={1} position="relative">
<iframe
src={embedUrl.toString()}
Expand All @@ -69,12 +70,21 @@ export function renderYoutubeVideoURL(match: URL) {
);
}

export function renderYoutubeVideoURL(match: URL) {
if (!YOUTUBE_DOMAINS.includes(match.hostname)) return null;
if (match.pathname.startsWith("/live")) return null;

var videoId = match.searchParams.get("v");
if (match.hostname === "youtu.be") videoId = match.pathname.split("/")[1];
if (!videoId) return null;

return <YoutubeVideoEmbed url={match} />;
}

// nostr:nevent1qqszwj6mk665ga4r25w5vzxmy9rsvqj42kk4gnkq2t2utljr6as948qpp4mhxue69uhkummn9ekx7mqprdmhxue69uhkvet9v3ejumn0wd68ytnzv9hxgtmdv4kk245xvyn
export function renderYoutubeURL(match: URL) {
if (!YOUTUBE_DOMAINS.includes(match.hostname)) return null;
if (match.pathname.startsWith("/live")) return null;

const { youtubeRedirect } = appSettings.value;

return renderYoutubePlaylistURL(match) || renderYoutubeVideoURL(match);
}
4 changes: 2 additions & 2 deletions src/components/note/timeline-note/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import UserLink from "../../user/user-link";
import NoteZapButton from "../note-zap-button";
import { ExpandProvider } from "../../../providers/local/expanded";
import useSubject from "../../../hooks/use-subject";
import appSettings from "../../../services/settings/app-settings";
import EventVerificationIcon from "../../common-event/event-verification-icon";
import RepostButton from "./components/repost-button";
import QuoteEventButton from "../quote-event-button";
Expand All @@ -48,6 +47,7 @@ import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
import relayHintService from "../../../services/event-relay-hint";
import localSettings from "../../../services/local-settings";
import NotePublishedUsing from "../note-published-using";
import useAppSettings from "../../../hooks/use-app-settings";

export type TimelineNoteProps = Omit<CardProps, "children"> & {
event: NostrEvent;
Expand All @@ -69,7 +69,7 @@ export function TimelineNote({
...props
}: TimelineNoteProps) {
const account = useCurrentAccount();
const { showReactions, showSignatureVerification } = useSubject(appSettings);
const { showReactions, showSignatureVerification } = useAppSettings();
const hideZapBubbles = useSubject(localSettings.hideZapBubbles);
const replyForm = useDisclosure();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ColorModeWithSystem } from "@chakra-ui/react";
import { NostrEvent } from "../../types/nostr-event";
import { safeJson } from "../../helpers/parse";
import { NostrEvent } from "../types/nostr-event";
import { safeJson } from "./parse";

export type AppSettingsV0 = {
version: 0;
Expand Down
Loading

0 comments on commit bb855a2

Please sign in to comment.