mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-13 06:09:42 +02:00
fix max page width option
This commit is contained in:
parent
07d2df7d5c
commit
5b2113b3b9
@ -13,6 +13,8 @@ import { getMatchLink } from "../../helpers/regexp";
|
||||
import TimelineHealth from "./timeline-health";
|
||||
import useRouteSearchValue from "../../hooks/use-route-search-value";
|
||||
import VerticalPageLayout from "../vertical-page-layout";
|
||||
import useAppSettings from "../../hooks/use-user-app-settings";
|
||||
import useMaxPageWidth from "../../hooks/use-max-page-width";
|
||||
|
||||
export function useTimelinePageEventFilter() {
|
||||
const [params, setParams] = useSearchParams();
|
||||
@ -40,6 +42,7 @@ export default function TimelinePage({
|
||||
>) {
|
||||
const callback = useTimelineCurserIntersectionCallback(loader);
|
||||
|
||||
const { maxPageWidth } = useAppSettings();
|
||||
const viewParam = useRouteSearchValue("view", "timeline");
|
||||
const mode = (viewParam.value as TimelineViewType) ?? "timeline";
|
||||
|
||||
@ -57,9 +60,11 @@ export default function TimelinePage({
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
const maxWidth = useMaxPageWidth("6xl");
|
||||
return (
|
||||
<IntersectionObserverProvider callback={callback}>
|
||||
<VerticalPageLayout maxW="6xl" mx="auto" {...props}>
|
||||
<VerticalPageLayout maxW={maxWidth} mx="auto" {...props}>
|
||||
{header}
|
||||
{renderTimeline()}
|
||||
<TimelineActionAndStatus timeline={loader} />
|
||||
|
@ -29,7 +29,7 @@ export type AppSettingsV0 = {
|
||||
export type AppSettingsV1 = Omit<AppSettingsV0, "version"> & {
|
||||
version: 1;
|
||||
mutedWords?: string;
|
||||
maxPageWidth: "none" | "md" | "lg" | "xl";
|
||||
maxPageWidth: "none" | "sm" | "md" | "lg" | "xl" | "full";
|
||||
};
|
||||
export type AppSettingsV2 = Omit<AppSettingsV1, "version"> & { version: 2; theme: string };
|
||||
export type AppSettingsV3 = Omit<AppSettingsV2, "version"> & { version: 3; quickReactions: string[] };
|
||||
|
21
src/hooks/use-max-page-width.ts
Normal file
21
src/hooks/use-max-page-width.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import useAppSettings from "./use-user-app-settings";
|
||||
|
||||
export default function useMaxPageWidth(fallback?: string) {
|
||||
const { maxPageWidth } = useAppSettings();
|
||||
|
||||
switch (maxPageWidth) {
|
||||
case "sm":
|
||||
return "2xl";
|
||||
case "md":
|
||||
return "4xl";
|
||||
case "lg":
|
||||
return "6xl";
|
||||
case "xl":
|
||||
return "8xl";
|
||||
case "full":
|
||||
return "full";
|
||||
default:
|
||||
case "none":
|
||||
return fallback || "6xl";
|
||||
}
|
||||
}
|
@ -15,11 +15,8 @@ import { queryStore } from "../../services/event-store";
|
||||
import EventFactoryProvider from "./event-factory-provider";
|
||||
|
||||
function ThemeProviders({ children }: { children: React.ReactNode }) {
|
||||
const { theme: themeName, primaryColor, maxPageWidth } = useAppSettings();
|
||||
const theme = useMemo(
|
||||
() => buildTheme(themeName, primaryColor, maxPageWidth !== "none" ? maxPageWidth : undefined),
|
||||
[themeName, primaryColor, maxPageWidth],
|
||||
);
|
||||
const { theme: themeName, primaryColor } = useAppSettings();
|
||||
const theme = useMemo(() => buildTheme(themeName, primaryColor), [themeName, primaryColor]);
|
||||
|
||||
return (
|
||||
<ChakraProvider theme={theme} colorModeManager={localStorageManager}>
|
||||
|
@ -17,13 +17,7 @@ function getTheme(name: string) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const breakpoints = ["sm", "md", "lg", "xl", "2xl"] as const;
|
||||
|
||||
export default function buildTheme(
|
||||
themeName: string,
|
||||
primaryColor: string = "#8DB600",
|
||||
maxBreakpoint?: (typeof breakpoints)[number],
|
||||
) {
|
||||
export default function buildTheme(themeName: string, primaryColor: string = "#8DB600") {
|
||||
const theme = extendTheme(getTheme(themeName), {
|
||||
config: {
|
||||
initialColorMode: "system",
|
||||
@ -46,12 +40,5 @@ export default function buildTheme(
|
||||
},
|
||||
} as DeepPartial<Theme>);
|
||||
|
||||
// if maxBreakpoint is set, set all breakpoints above it to a large number so they are never reached
|
||||
if (maxBreakpoint && breakpoints.includes(maxBreakpoint)) {
|
||||
for (let i = breakpoints.indexOf(maxBreakpoint) + 1; i < breakpoints.length; i++) {
|
||||
theme.breakpoints[breakpoints[i]] = 50000;
|
||||
}
|
||||
}
|
||||
|
||||
return theme;
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ import ArticleCard from "./components/article-card";
|
||||
import PeopleListSelection from "../../components/people-list-selection/people-list-selection";
|
||||
import { getArticleTitle } from "../../helpers/nostr/long-form";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import useMaxPageWidth from "../../hooks/use-max-page-width";
|
||||
|
||||
function ArticlesHomePage() {
|
||||
const relays = useReadRelays();
|
||||
@ -41,8 +42,10 @@ function ArticlesHomePage() {
|
||||
});
|
||||
const callback = useTimelineCurserIntersectionCallback(loader);
|
||||
|
||||
const maxWidth = useMaxPageWidth();
|
||||
|
||||
return (
|
||||
<VerticalPageLayout maxW="6xl" mx="auto">
|
||||
<VerticalPageLayout maxW={maxWidth} mx="auto">
|
||||
<Flex gap="2">
|
||||
<Heading>Articles</Heading>
|
||||
<PeopleListSelection />
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { AddressPointer, EventPointer } from "nostr-tools/nip19";
|
||||
import { Button, ButtonGroup, Flex, Heading, SimpleGrid, SkeletonText, Spinner } from "@chakra-ui/react";
|
||||
import { Button, ButtonGroup, Flex, Heading, SkeletonText, Spinner } from "@chakra-ui/react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { NostrEvent } from "nostr-tools";
|
||||
import { getAddressPointerFromATag, getEventPointerFromETag, isATag, isETag } from "applesauce-core/helpers";
|
||||
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import TimelineItem from "../../components/timeline-page/generic-note-timeline/timeline-item";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
@ -10,13 +11,12 @@ import userUserBookmarksList from "../../hooks/use-user-bookmarks-list";
|
||||
import UserName from "../../components/user/user-name";
|
||||
import ListMenu from "../lists/components/list-menu";
|
||||
import UserAvatarLink from "../../components/user/user-avatar-link";
|
||||
import { NostrEvent, isATag, isETag } from "../../types/nostr-event";
|
||||
import useEventBookmarkActions from "../../hooks/use-event-bookmark-actions";
|
||||
import useParamsProfilePointer from "../../hooks/use-params-pubkey-pointer";
|
||||
import useReplaceableEvent from "../../hooks/use-replaceable-event";
|
||||
import { EmbedEvent } from "../../components/embed-event";
|
||||
import { aTagToAddressPointer, eTagToEventPointer } from "../../helpers/nostr/event";
|
||||
import SimpleView from "../../components/layout/presets/simple-view";
|
||||
import useMaxPageWidth from "../../hooks/use-max-page-width";
|
||||
|
||||
function RemoveBookmarkButton({ event }: { event: NostrEvent }) {
|
||||
const { isLoading, removeBookmark } = useEventBookmarkActions(event);
|
||||
@ -57,6 +57,7 @@ function BookmarkAddressItem({ pointer }: { pointer: AddressPointer }) {
|
||||
|
||||
function BookmarksPage({ pubkey }: { pubkey: string }) {
|
||||
const { list } = userUserBookmarksList(pubkey, undefined, true);
|
||||
const maxWidth = useMaxPageWidth();
|
||||
|
||||
if (!list) return <Spinner />;
|
||||
|
||||
@ -72,17 +73,17 @@ function BookmarksPage({ pubkey }: { pubkey: string }) {
|
||||
</Flex>
|
||||
}
|
||||
actions={<ListMenu ml="auto" size="sm" list={list} aria-label="More options" />}
|
||||
maxW="4xl"
|
||||
maxW={maxWidth}
|
||||
center
|
||||
>
|
||||
{Array.from(list.tags)
|
||||
.reverse()
|
||||
.map((tag) => {
|
||||
if (isETag(tag)) {
|
||||
const pointer = eTagToEventPointer(tag);
|
||||
const pointer = getEventPointerFromETag(tag);
|
||||
return <BookmarkEventItem key={pointer.id} pointer={pointer} />;
|
||||
} else if (isATag(tag)) {
|
||||
const pointer = aTagToAddressPointer(tag);
|
||||
const pointer = getAddressPointerFromATag(tag);
|
||||
return <BookmarkAddressItem key={tag[1]} pointer={pointer} />;
|
||||
}
|
||||
return null;
|
||||
|
@ -34,6 +34,7 @@ import NoteReactions from "../../../components/note/timeline-note/components/not
|
||||
import FileMenu from "../components/file-menu";
|
||||
import EventShareButton from "../../../components/note/timeline-note/components/event-share-button";
|
||||
import { formatBytes } from "../../../helpers/number";
|
||||
import useMaxPageWidth from "../../../hooks/use-max-page-width";
|
||||
|
||||
function FileDetailsPage({ file }: { file: NostrEvent }) {
|
||||
const name = getTagValue(file, "name") || getTagValue(file, "x");
|
||||
@ -44,6 +45,8 @@ function FileDetailsPage({ file }: { file: NostrEvent }) {
|
||||
const sha256 = getTagValue(file, "x");
|
||||
const comment = useDisclosure();
|
||||
|
||||
const maxWidth = useMaxPageWidth();
|
||||
|
||||
return (
|
||||
<VerticalPageLayout>
|
||||
<Flex gap="2" alignItems="center">
|
||||
@ -61,7 +64,7 @@ function FileDetailsPage({ file }: { file: NostrEvent }) {
|
||||
|
||||
<Flex
|
||||
direction="column"
|
||||
maxW="6xl"
|
||||
maxW={maxWidth}
|
||||
mx="auto"
|
||||
w="full"
|
||||
maxH="2xl"
|
||||
@ -74,7 +77,7 @@ function FileDetailsPage({ file }: { file: NostrEvent }) {
|
||||
</TrustProvider>
|
||||
</Flex>
|
||||
|
||||
<Flex mx="auto" maxW="6xl" w="full" gap="2" direction="column">
|
||||
<Flex mx="auto" maxW={maxWidth} w="full" gap="2" direction="column">
|
||||
<Flex gap="2">
|
||||
{type && <Text>{type}</Text>}
|
||||
{size && <Text>{formatBytes(parseInt(size))}</Text>}
|
||||
@ -89,7 +92,7 @@ function FileDetailsPage({ file }: { file: NostrEvent }) {
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Divider mx="auto" maxW="6xl" w="full" />
|
||||
<Divider mx="auto" maxW={maxWidth} w="full" />
|
||||
{summary && <Text whiteSpace="pre-line">{summary}</Text>}
|
||||
<Flex gap="2" wrap="wrap">
|
||||
<ButtonGroup gap="2" size="sm" variant="ghost">
|
||||
|
@ -3,7 +3,6 @@ import { useNavigate } from "react-router-dom";
|
||||
import { PasswordSigner, SerialPortSigner, SimpleSigner } from "applesauce-signer";
|
||||
import { useObservable } from "applesauce-react/hooks";
|
||||
|
||||
import VerticalPageLayout from "../../../components/vertical-page-layout";
|
||||
import useCurrentAccount from "../../../hooks/use-current-account";
|
||||
import UserAvatar from "../../../components/user/user-avatar";
|
||||
import UserName from "../../../components/user/user-name";
|
||||
@ -11,10 +10,7 @@ import UserDnsIdentity from "../../../components/user/user-dns-identity";
|
||||
import accountService from "../../../services/account";
|
||||
import AccountTypeBadge from "../../../components/account-info-badge";
|
||||
import SimpleSignerBackup from "./components/simple-signer-backup";
|
||||
import PasswordSignerBackup from "./components/password-signer-backup";
|
||||
import { ReactNode } from "react";
|
||||
import MigrateAccountToDevice from "./components/migrate-to-device";
|
||||
import SimpleHeader from "../../../components/layout/presets/simple-header";
|
||||
import SimpleView from "../../../components/layout/presets/simple-view";
|
||||
|
||||
function AccountBackup() {
|
||||
|
@ -74,13 +74,15 @@ export default function DisplaySettings() {
|
||||
Max Page width
|
||||
</FormLabel>
|
||||
<Select id="maxPageWidth" {...register("maxPageWidth")} maxW="sm">
|
||||
<option value="none">None</option>
|
||||
<option value="md">Medium (~768px)</option>
|
||||
<option value="lg">Large (~992px)</option>
|
||||
<option value="xl">Extra Large (~1280px)</option>
|
||||
<option value="none">Default</option>
|
||||
<option value="full">Full</option>
|
||||
<option value="sm">Small</option>
|
||||
<option value="md">Medium</option>
|
||||
<option value="lg">Large</option>
|
||||
<option value="xl">Extra Large</option>
|
||||
</Select>
|
||||
<FormHelperText>
|
||||
<span>Setting this will restrict the width of app on desktop</span>
|
||||
<span>Setting this will restrict the width of the timeline</span>
|
||||
</FormHelperText>
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
|
@ -19,6 +19,7 @@ import UserAvatarLink from "../../components/user/user-avatar-link";
|
||||
import { ReplyIcon } from "../../components/icons";
|
||||
import TimelineNote from "../../components/note/timeline-note";
|
||||
import { getSharableEventAddress } from "../../services/relay-hints";
|
||||
import useMaxPageWidth from "../../hooks/use-max-page-width";
|
||||
|
||||
function CollapsedReplies({
|
||||
pointer,
|
||||
@ -109,8 +110,9 @@ export default function ThreadView() {
|
||||
|
||||
const callback = useTimelineCurserIntersectionCallback(timeline);
|
||||
|
||||
const maxWidth = useMaxPageWidth("6xl");
|
||||
return (
|
||||
<VerticalPageLayout maxW="6xl" mx="auto" w="full">
|
||||
<VerticalPageLayout maxW={maxWidth} mx="auto" w="full">
|
||||
{!focusedEvent && (
|
||||
<>
|
||||
<Heading my="4">
|
||||
|
@ -9,6 +9,7 @@ import TimelineActionAndStatus from "../../components/timeline/timeline-action-a
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import ArticleCard from "../articles/components/article-card";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import useMaxPageWidth from "../../hooks/use-max-page-width";
|
||||
|
||||
export default function UserArticlesTab() {
|
||||
const { pubkey } = useOutletContext() as { pubkey: string };
|
||||
@ -20,9 +21,11 @@ export default function UserArticlesTab() {
|
||||
});
|
||||
const callback = useTimelineCurserIntersectionCallback(loader);
|
||||
|
||||
const maxWidth = useMaxPageWidth();
|
||||
|
||||
return (
|
||||
<IntersectionObserverProvider callback={callback}>
|
||||
<VerticalPageLayout maxW="6xl" mx="auto">
|
||||
<VerticalPageLayout maxW={maxWidth} mx="auto">
|
||||
{articles?.map((article) => (
|
||||
<ErrorBoundary key={article.id} event={article}>
|
||||
<ArticleCard article={article} />
|
||||
|
Loading…
x
Reference in New Issue
Block a user