From 99bbd3eeabccd9fb7481f200fd13dcc600e4e790 Mon Sep 17 00:00:00 2001 From: thislight Date: Wed, 9 Oct 2024 18:45:19 +0800 Subject: [PATCH] add settings for autoplay gifs and vids --- src/App.tsx | 6 +- src/settings/Motions.tsx | 89 +++++++++++++++++++++++++++ src/settings/Settings.tsx | 30 +++++++-- src/settings/i18n/en.json | 10 ++- src/settings/i18n/zh-Hans.json | 10 ++- src/settings/stores.ts | 4 ++ src/timelines/MediaAttachmentGrid.tsx | 18 ++++-- 7 files changed, 153 insertions(+), 14 deletions(-) create mode 100644 src/settings/Motions.tsx diff --git a/src/App.tsx b/src/App.tsx index 6ed8a9b..69249b3 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -25,13 +25,17 @@ const AccountMastodonOAuth2Callback = lazy( const TimelineHome = lazy(() => import("./timelines/Home.js")); const Settings = lazy(() => import("./settings/Settings.js")); const TootBottomSheet = lazy(() => import("./timelines/TootBottomSheet.js")); +const MotionSettings = lazy(() => import("./settings/Motions.js")); const Routing: Component = () => { return ( - + + + + diff --git a/src/settings/Motions.tsx b/src/settings/Motions.tsx new file mode 100644 index 0000000..2f111fd --- /dev/null +++ b/src/settings/Motions.tsx @@ -0,0 +1,89 @@ +import type { Component } from "solid-js"; +import Scaffold from "../material/Scaffold"; +import { + AppBar, + Divider, + IconButton, + List, + ListItemButton, + ListItemSecondaryAction, + ListItemText, + ListSubheader, + Switch, + Toolbar, +} from "@suid/material"; +import { Title } from "../material/typography"; +import { useNavigate } from "@solidjs/router"; +import { Close as CloseIcon } from "@suid/icons-material"; +import { createTranslator } from "../platform/i18n"; +import { useStore } from "@nanostores/solid"; +import { $settings } from "./stores"; + +const Motions: Component = () => { + const navigate = useNavigate(); + const [t] = createTranslator( + (code) => + import(`./i18n/${code}.json`) as Promise<{ + default: Record; + }>, + ); + const settings = useStore($settings); + return ( + + + + + + {t("motions")} + + + } + > + +
  • +
      + {t("motions.gifs")} + + $settings.setKey("autoPlayGIFs", !settings().autoPlayGIFs) + } + > + {t("motions.gifs.autoplay")} + + + + + +
    +
  • +
  • +
      + {t("motions.vids")} + + $settings.setKey("autoPlayVideos", !settings().autoPlayVideos) + } + > + {t("motions.vids.autoplay")} + + + + + +
    +
  • +
    +
    + ); +}; + +export default Motions; diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index ad9f66b..e27443a 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -1,4 +1,10 @@ -import { createSignal, For, Show, type ParentComponent } from "solid-js"; +import { + children, + createSignal, + For, + Show, + type ParentComponent, +} from "solid-js"; import Scaffold from "../material/Scaffold.js"; import { AppBar, @@ -11,18 +17,18 @@ import { ListItemSecondaryAction, ListItemText, ListSubheader, - NativeSelect, Switch, Toolbar, } from "@suid/material"; import { + Animation as AnimationIcon, Close as CloseIcon, Logout, Public as PublicIcon, Refresh as RefreshIcon, Translate as TranslateIcon, } from "@suid/icons-material"; -import { useNavigate } from "@solidjs/router"; +import { A, useNavigate } from "@solidjs/router"; import { Title } from "../material/typography.jsx"; import { css } from "solid-styled"; import { useSignedInProfiles } from "../masto/acct.js"; @@ -43,12 +49,13 @@ import { type Template } from "@solid-primitives/i18n"; import BottomSheet from "../material/BottomSheet.jsx"; import ChooseLang from "./ChooseLang.jsx"; import ChooseRegion from "./ChooseRegion.jsx"; +import { Portal } from "solid-js/web"; type Strings = { ["lang.auto"]: Template<{ detected: string }>; } & Record; -const Settings: ParentComponent = () => { +const Settings: ParentComponent = (props) => { const [t] = createTranslator( (code) => import(`./i18n/${code}.json`) as Promise<{ @@ -71,6 +78,8 @@ const Settings: ParentComponent = () => { signOut((a) => a.site === acct.site && a.accessToken === acct.accessToken); }; + const subpage = children(() => props.children); + css` ul { padding: 0; @@ -96,6 +105,10 @@ const Settings: ParentComponent = () => { } > + navigate(-1)}> + {subpage()} + +
    • @@ -135,7 +148,7 @@ const Settings: ParentComponent = () => {
    • - {t("Reading")} + {t("timelines")} $settings.setKey( @@ -152,6 +165,13 @@ const Settings: ParentComponent = () => { + + + + + {t("motions")} + +
    • {t("This Application")} diff --git a/src/settings/i18n/en.json b/src/settings/i18n/en.json index 095bc04..98424be 100644 --- a/src/settings/i18n/en.json +++ b/src/settings/i18n/en.json @@ -3,7 +3,7 @@ "Accounts": "Accounts", "All Notifications": "All Notifications", "Sign in...": "Sign in...", - "Reading": "Reading", + "timelines": "Timelines and Toot Lists", "Prefetch Toots": "Prefetch Toots", "Prefetch Toots.2nd": "Tutu will download the toots before you need.", "This Application": "This Application", @@ -26,5 +26,11 @@ "Choose Language": "Choose Language", "Supported": "Supported", "Unsupported": "Unsupported", - "Choose Region": "Choose Region" + "Choose Region": "Choose Region", + + "motions": "GIFs and Videos", + "motions.gifs": "GIFs", + "motions.gifs.autoplay": "Auto-play GIFs", + "motions.vids": "Videos", + "motions.vids.autoplay": "Auto-play Videos" } \ No newline at end of file diff --git a/src/settings/i18n/zh-Hans.json b/src/settings/i18n/zh-Hans.json index 8fd70d1..481d57c 100644 --- a/src/settings/i18n/zh-Hans.json +++ b/src/settings/i18n/zh-Hans.json @@ -3,7 +3,7 @@ "Accounts": "所有账户", "All Notifications": "所有通知", "Sign in...": "登录新账户...", - "Reading": "阅读", + "timelines": "时间线和嘟文列表", "Prefetch Toots": "提前下载嘟文", "Prefetch Toots.2nd": "图图会在你可能需要的时候提前下载嘟文。", "This Application": "本应用", @@ -26,5 +26,11 @@ "Choose Language": "选择语言", "Supported": "已支持", "Unsupported": "尚未支持", - "Choose Region": "选择区域" + "Choose Region": "选择区域", + + "motions": "动图和视频", + "motions.gifs": "动图", + "motions.gifs.autoplay": "自动播放动图", + "motions.vids": "视频", + "motions.vids.autoplay": "自动播放视频" } \ No newline at end of file diff --git a/src/settings/stores.ts b/src/settings/stores.ts index 151f449..0d392e2 100644 --- a/src/settings/stores.ts +++ b/src/settings/stores.ts @@ -5,6 +5,10 @@ type Settings = { prefetchTootsDisabled?: boolean; language?: string; region?: string; + + // GIFs and Videos + autoPlayGIFs?: boolean; + autoPlayVideos?: boolean; }; export const $settings = persistentMap( diff --git a/src/timelines/MediaAttachmentGrid.tsx b/src/timelines/MediaAttachmentGrid.tsx index 5748f0d..0fa0b1c 100644 --- a/src/timelines/MediaAttachmentGrid.tsx +++ b/src/timelines/MediaAttachmentGrid.tsx @@ -13,6 +13,8 @@ import tootStyle from "./toot.module.css"; import MediaViewer from "./MediaViewer"; import { render } from "solid-js/web"; import { useWindowSize } from "@solid-primitives/resize-observer"; +import { useStore } from "@nanostores/solid"; +import { $settings } from "../settings/stores"; const MediaAttachmentGrid: Component<{ attachments: mastodon.v1.MediaAttachment[]; @@ -22,6 +24,7 @@ const MediaAttachmentGrid: Component<{ const viewerOpened = () => typeof viewerIndex() !== "undefined"; const windowSize = useWindowSize(); const vh35 = () => Math.floor(windowSize.height * 0.35); + const settings = useStore($settings); createRenderEffect((lastDispose?: () => void) => { lastDispose?.(); @@ -70,7 +73,11 @@ const MediaAttachmentGrid: Component<{
      e.stopImmediatePropagation()} + onClick={(e) => { + if (e.target !== e.currentTarget) { + e.stopImmediatePropagation(); + } + }} > {(item, index) => { @@ -109,20 +116,23 @@ const MediaAttachmentGrid: Component<{ src={item.url || undefined} style={style()} onLoadedMetadata={[setLoaded, true]} - autoplay={false} + autoplay={settings().autoPlayVideos} + playsinline={settings().autoPlayVideos ? true : undefined} controls + poster={item.previewUrl} /> ); - case "gifv": // Later we can handle the preview + case "gifv": return (