add settings for autoplay gifs and vids
All checks were successful
/ depoly (push) Successful in 1m0s
All checks were successful
/ depoly (push) Successful in 1m0s
This commit is contained in:
parent
d44a90ab49
commit
99bbd3eeab
7 changed files with 153 additions and 14 deletions
|
@ -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 (
|
||||
<Router>
|
||||
<Route path="/" component={TimelineHome}>
|
||||
<Route path=""></Route>
|
||||
<Route path="/settings" component={Settings}></Route>
|
||||
<Route path="/settings" component={Settings}>
|
||||
<Route path=""></Route>
|
||||
<Route path="/motions" component={MotionSettings}></Route>
|
||||
</Route>
|
||||
<Route path="/:acct/:id" component={TootBottomSheet}></Route>
|
||||
</Route>
|
||||
<Route path={"/accounts"}>
|
||||
|
|
89
src/settings/Motions.tsx
Normal file
89
src/settings/Motions.tsx
Normal file
|
@ -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<string, string | undefined>;
|
||||
}>,
|
||||
);
|
||||
const settings = useStore($settings);
|
||||
return (
|
||||
<Scaffold
|
||||
topbar={
|
||||
<AppBar position="static">
|
||||
<Toolbar
|
||||
variant="dense"
|
||||
sx={{ paddingTop: "var(--safe-area-inset-top, 0px)" }}
|
||||
>
|
||||
<IconButton color="inherit" onClick={[navigate, -1]} disableRipple>
|
||||
<CloseIcon />
|
||||
</IconButton>
|
||||
<Title>{t("motions")}</Title>
|
||||
</Toolbar>
|
||||
</AppBar>
|
||||
}
|
||||
>
|
||||
<List
|
||||
sx={{
|
||||
paddingBottom: "calc(var(--safe-area-inset-bottom, 0px) + 16px)",
|
||||
}}
|
||||
>
|
||||
<li>
|
||||
<ul style={{ "padding-left": 0 }}>
|
||||
<ListSubheader>{t("motions.gifs")}</ListSubheader>
|
||||
<ListItemButton
|
||||
onClick={() =>
|
||||
$settings.setKey("autoPlayGIFs", !settings().autoPlayGIFs)
|
||||
}
|
||||
>
|
||||
<ListItemText>{t("motions.gifs.autoplay")}</ListItemText>
|
||||
<ListItemSecondaryAction>
|
||||
<Switch checked={settings().autoPlayGIFs}></Switch>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItemButton>
|
||||
<Divider />
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
<ul style={{ "padding-left": 0 }}>
|
||||
<ListSubheader>{t("motions.vids")}</ListSubheader>
|
||||
<ListItemButton
|
||||
onClick={() =>
|
||||
$settings.setKey("autoPlayVideos", !settings().autoPlayVideos)
|
||||
}
|
||||
>
|
||||
<ListItemText>{t("motions.vids.autoplay")}</ListItemText>
|
||||
<ListItemSecondaryAction>
|
||||
<Switch checked={settings().autoPlayVideos}></Switch>
|
||||
</ListItemSecondaryAction>
|
||||
</ListItemButton>
|
||||
<Divider />
|
||||
</ul>
|
||||
</li>
|
||||
</List>
|
||||
</Scaffold>
|
||||
);
|
||||
};
|
||||
|
||||
export default Motions;
|
|
@ -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<string, string | undefined>;
|
||||
|
||||
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 = () => {
|
|||
</AppBar>
|
||||
}
|
||||
>
|
||||
<BottomSheet open={!!subpage()} onClose={() => navigate(-1)}>
|
||||
{subpage()}
|
||||
</BottomSheet>
|
||||
|
||||
<List class="setting-list" use:solid-styled>
|
||||
<li>
|
||||
<ul>
|
||||
|
@ -135,7 +148,7 @@ const Settings: ParentComponent = () => {
|
|||
</For>
|
||||
</li>
|
||||
<li>
|
||||
<ListSubheader>{t("Reading")}</ListSubheader>
|
||||
<ListSubheader>{t("timelines")}</ListSubheader>
|
||||
<ListItemButton
|
||||
onClick={(e) =>
|
||||
$settings.setKey(
|
||||
|
@ -152,6 +165,13 @@ const Settings: ParentComponent = () => {
|
|||
</ListItemSecondaryAction>
|
||||
</ListItemButton>
|
||||
<Divider />
|
||||
<ListItemButton component={A} href="./motions">
|
||||
<ListItemIcon>
|
||||
<AnimationIcon></AnimationIcon>
|
||||
</ListItemIcon>
|
||||
<ListItemText>{t("motions")}</ListItemText>
|
||||
</ListItemButton>
|
||||
<Divider />
|
||||
</li>
|
||||
<li>
|
||||
<ListSubheader>{t("This Application")}</ListSubheader>
|
||||
|
|
|
@ -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"
|
||||
}
|
|
@ -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": "自动播放视频"
|
||||
}
|
|
@ -5,6 +5,10 @@ type Settings = {
|
|||
prefetchTootsDisabled?: boolean;
|
||||
language?: string;
|
||||
region?: string;
|
||||
|
||||
// GIFs and Videos
|
||||
autoPlayGIFs?: boolean;
|
||||
autoPlayVideos?: boolean;
|
||||
};
|
||||
|
||||
export const $settings = persistentMap<Settings>(
|
||||
|
|
|
@ -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<{
|
|||
<section
|
||||
ref={rootRef!}
|
||||
class={[tootStyle.tootAttachmentGrp, "attachments"].join(" ")}
|
||||
onClick={(e) => e.stopImmediatePropagation()}
|
||||
onClick={(e) => {
|
||||
if (e.target !== e.currentTarget) {
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<For each={props.attachments}>
|
||||
{(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 (
|
||||
<video
|
||||
src={item.url || undefined}
|
||||
style={style()}
|
||||
onLoadedMetadata={[setLoaded, true]}
|
||||
autoplay={false}
|
||||
autoplay={settings().autoPlayGIFs}
|
||||
controls
|
||||
playsinline /* or safari on iOS will play in full-screen */
|
||||
loop
|
||||
poster={item.previewUrl}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue