diff --git a/web/src/lib/i18n/locales/en.json b/web/src/lib/i18n/locales/en.json index 0fb76f5e..5e493ce9 100644 --- a/web/src/lib/i18n/locales/en.json +++ b/web/src/lib/i18n/locales/en.json @@ -348,7 +348,11 @@ "send": "Zap" }, "timeline": { - "update": "Show new posts" + "update": "Show new posts", + "options": { + "title": "Options", + "speech": "Speech" + } }, "emoji": { "custom": { diff --git a/web/src/lib/i18n/locales/ja.json b/web/src/lib/i18n/locales/ja.json index 220a3d10..81c25531 100644 --- a/web/src/lib/i18n/locales/ja.json +++ b/web/src/lib/i18n/locales/ja.json @@ -347,7 +347,11 @@ "send": "Zap" }, "timeline": { - "update": "新しい投稿を表示" + "update": "新しい投稿を表示", + "options": { + "title": "オプション", + "speech": "読み上げ" + } }, "emoji": { "custom": { diff --git a/web/src/lib/timelines/HomeTimeline.ts b/web/src/lib/timelines/HomeTimeline.ts index 70c4c87d..21bd5dd0 100644 --- a/web/src/lib/timelines/HomeTimeline.ts +++ b/web/src/lib/timelines/HomeTimeline.ts @@ -12,7 +12,7 @@ import { import { filter, share, tap } from 'rxjs'; import type { Event } from 'nostr-typedef'; import { referencesReqEmit, rxNostr, storeSeenOn, tie } from './MainTimeline'; -import { WebStorage } from '$lib/WebStorage'; +import { persistedStore, WebStorage } from '$lib/WebStorage'; import { kinds as Kind } from 'nostr-tools'; import { get, writable } from 'svelte/store'; import { bookmarkEvent } from '$lib/author/Bookmark'; @@ -253,7 +253,14 @@ export class HomeTimeline extends NewTimeline { filterByKind(Kind.ShortTextNote), tap(({ event }) => userStatusReqEmit([event.pubkey])) ) - .subscribe(({ event }) => saveLastNote(event)); + .subscribe(({ event }) => { + saveLastNote(event); + + if (get(options).speech) { + const utterance = new SpeechSynthesisUtterance(event.content); + window.speechSynthesis.speak(utterance); + } + }); } #createForwardFilters(): LazyFilter[] { @@ -504,3 +511,4 @@ export class HomeTimeline extends NewTimeline { } export const timeline = new HomeTimeline(); +export const options = persistedStore('preference:timeline:home:options', { speech: false }); diff --git a/web/src/routes/(app)/home/+page.svelte b/web/src/routes/(app)/home/+page.svelte index a28627af..eb9bd904 100644 --- a/web/src/routes/(app)/home/+page.svelte +++ b/web/src/routes/(app)/home/+page.svelte @@ -2,7 +2,7 @@ import { onMount } from 'svelte'; import { goto } from '$app/navigation'; import { followees, author } from '$lib/stores/Author'; - import { timeline } from '$lib/timelines/HomeTimeline'; + import { options, timeline } from '$lib/timelines/HomeTimeline'; import { applyTimelieFilter } from '$lib/TimelineFilter'; import { _ } from 'svelte-i18n'; import { IconAdjustmentsHorizontal } from '@tabler/icons-svelte'; @@ -42,6 +42,15 @@

{$_('preferences.timeline_filter.title')}

+
+

{$_('timeline.options.title')}

+
+ +
+
{#if $author !== undefined}