enhancements/low-data-mode #726

Closed
trycatchkamal wants to merge 3 commits from trycatchkamal/snort:enhancements/low-data-mode into main
9 changed files with 75 additions and 8 deletions

View File

@ -197,6 +197,9 @@ export default function NoteFooter(props: NoteFooterProps) {
}
function tipButton() {
if(prefs.lowDataMode){
return null;
}
const targets = getZapTarget();
if (targets) {
return (
@ -214,7 +217,12 @@ export default function NoteFooter(props: NoteFooterProps) {
}
function repostIcon() {
if (readonly) return;
if (readonly) {
return;
}
else if(prefs.lowDataMode){
return null;
}
return (
<Menu
menuButton={
@ -254,7 +262,7 @@ export default function NoteFooter(props: NoteFooterProps) {
}
function reactionIcon() {
if (!prefs.enableReactions) {
if (!prefs.enableReactions || prefs.lowDataMode){
return null;
}
const reacted = hasReacted("+");

View File

@ -39,8 +39,13 @@ export function NoteInner(props: NoteProps) {
const { isEventMuted } = useModeration();
const { ref, inView } = useInView({ triggerOnce: true, rootMargin: "2000px" });
const { reactions, reposts, deletions, zaps } = useEventReactions(NostrLink.fromEvent(ev), related);
const login = useLogin();
const { preferences } = useLogin(s => ({ preferences: s.appData.item.preferences }));
const { reactions, reposts, deletions, zaps } = preferences.lowDataMode? {reactions:{
all: [],
positive: [],
negative: [],
}, reposts:[], deletions:[], zaps:[]} : useEventReactions(NostrLink.fromEvent(ev), related);
const { pinned, bookmarked } = useLogin();
const { publisher, system } = useEventPublisher();
const [translated, setTranslated] = useState<NoteTranslation>();

View File

@ -25,7 +25,7 @@ export default function RevealMedia(props: RevealMediaProps) {
const isMine = props.creator === publicKey;
const hideMedia = preferences.autoLoadMedia === "none" || (!isMine && hideNonFollows);
const hostname = new URL(props.link).hostname;
const lowDataMode = preferences.lowDataMode;
const url = new URL(props.link);
const extension = FileExtensionRegex.test(url.pathname.toLowerCase()) && RegExp.$1;
const type = (() => {
@ -76,7 +76,29 @@ export default function RevealMedia(props: RevealMediaProps) {
/>
</Reveal>
);
} else {
} else if(lowDataMode) {
return (
<Reveal
message={
<FormattedMessage
defaultMessage="Images will not be loaded automatically in low data mode, update <a><i>your preference</i></a> to show media as per your media preference."
id="VfHIx1"
values={{
i: i => <i>{i}</i>,
a: a => <Link to="/settings/preferences">{a}</Link>,
}}
/>
}>
<MediaElement
mime={`${type}/${extension}`}
url={url.toString()}
onMediaClick={props.onMediaClick}
meta={props.meta}
/>
</Reveal>
);
}
else{
return (
<MediaElement
mime={`${type}/${extension}`}

View File

@ -1,10 +1,12 @@
import { useEffect, useMemo, useState } from "react";
import { EventKind, NostrLink, RequestBuilder, NoteCollection, EventExt } from "@snort/system";
import { useReactions, useRequestBuilder } from "@snort/system-react";
import useLogin from "@/Hooks/useLogin";
export default function useThreadFeed(link: NostrLink) {
const [root, setRoot] = useState<NostrLink>();
const [allEvents, setAllEvents] = useState<Array<NostrLink>>([]);
const { preferences } = useLogin(s => ({ preferences: s.appData.item.preferences }));
const sub = useMemo(() => {
const sub = new RequestBuilder(`thread:${link.id.slice(0, 12)}`);
@ -62,7 +64,7 @@ export default function useThreadFeed(link: NostrLink) {
}
}, [store.data?.length]);
const reactions = useReactions(`thread:${link.id.slice(0, 12)}:reactions`, [link, ...allEvents]);
const reactions = preferences.lowDataMode ? [] :useReactions(`thread:${link.id.slice(0, 12)}:reactions`, [link, ...allEvents]);
return {
thread: store.data ?? [],

View File

@ -131,7 +131,7 @@ export default function useTimelineFeed(subject: TimelineSubject, options: Timel
}, [pref.autoShowLatest, createBuilder]);
const latest = useRequestBuilder(NoteCollection, subRealtime);
const reactions = useReactions(`${sub?.id}-reactions`, main.data?.map(a => NostrLink.fromEvent(a)) ?? []);
const reactions = pref.lowDataMode? [] : useReactions(`${sub?.id}-reactions`, main.data?.map(a => NostrLink.fromEvent(a)) ?? []);
return {
main: main.data,

View File

@ -5,6 +5,7 @@ import useThreadFeed from "@/Feed/ThreadFeed";
import { ReactNode, createContext, useMemo, useState } from "react";
import { useLocation } from "react-router-dom";
import useModeration from "./useModeration";
import useLogin from "./useLogin";
export interface ThreadContext {
current: string;
@ -38,6 +39,7 @@ export function ThreadContextWrapper({ link, children }: { link: NostrLink; chil
const [currentId, setCurrentId] = useState(unwrap(link.toEventTag())[1]);
const feed = useThreadFeed(link);
const { isBlocked } = useModeration();
const { preferences } = useLogin(s => ({ preferences: s.appData.item.preferences }));
const chains = useMemo(() => {
const chains = new Map<u256, Array<TaggedNostrEvent>>();
@ -79,7 +81,7 @@ export function ThreadContextWrapper({ link, children }: { link: NostrLink; chil
current: currentId,
root,
chains,
reactions: feed.reactions,
reactions: preferences.lowDataMode? [] : feed.reactions,
data: feed.thread,
setCurrent: v => setCurrentId(v),
};

View File

@ -96,6 +96,11 @@ export interface UserPreferences {
* Auto-translate when available
*/
autoTranslate?: boolean;
/**
* Low Data mode - images/reactions wont be loaded
*/
lowDataMode: boolean;
}
export const DefaultPreferences = {
@ -116,4 +121,5 @@ export const DefaultPreferences = {
showStatus: true,
checkSigs: true,
autoTranslate: true,
lowDataMode: false
} as UserPreferences;

View File

@ -497,6 +497,23 @@ const PreferencesPage = () => {
/>
</div>
</div>
<div className="flex justify-between">
<div className="flex flex-col g8">
<h4>
<FormattedMessage {...messages.LowDataMode} />
</h4>
<small>
<FormattedMessage {...messages.LowDataModeHelp} />
</small>
</div>
<div>
<input
type="checkbox"
checked={perf.lowDataMode}
onChange={e => updatePreferences(id, { ...perf, lowDataMode: e.target.checked })}
/>
</div>
</div>
</div>
);
};

View File

@ -76,4 +76,9 @@ export default defineMessages({
ServiceWorkerNotRunning: { defaultMessage: "Service Worker Not Running", id: "RDha9y" },
SubscribedToPush: { defaultMessage: "Subscribed to Push", id: "G3A56c" },
NotSubscribedToPush: { defaultMessage: "Not Subscribed to Push", id: "d2ebEu" },
LowDataMode: { defaultMessage: "Low Data Mode", id: '87tg/I' },
LowDataModeHelp: {
defaultMessage: "Reactions/Reposts/Zaps will not be shown on timeline and images would not load automatically",
id: 'dmSMtS',
},
});