feat(desktop): notifications settings
This commit is contained in:
parent
04cc13bef7
commit
0db149fe12
|
|
@ -4,6 +4,8 @@ import { atom } from "jotai"
|
|||
import { createAtomHooks } from "~/lib/jotai"
|
||||
|
||||
export const [, , useAppIsReady, , appIsReady, setAppIsReady] = createAtomHooks(atom(false))
|
||||
export const [, , useAppMessagingToken, , appMessagingToken, setAppMessagingToken] =
|
||||
createAtomHooks(atom<string | null>(null))
|
||||
|
||||
export const [, , useAppSearchOpen, , , setAppSearchOpen] = createAtomHooks(atom(false))
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ export const TargetActionList = ({ index }: { index: number }) => {
|
|||
},
|
||||
{
|
||||
title: t("actions.action_card.new_entry_notification"),
|
||||
icon: <i className="i-mgc-bell-ringing-cute-re" />,
|
||||
icon: <i className="i-mgc-notification-cute-re" />,
|
||||
enabled: !!newEntryNotification,
|
||||
onInit: (data) => {
|
||||
data.result.newEntryNotification = true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,115 @@
|
|||
import { Button } from "@follow/components/ui/button/index.js"
|
||||
import { Divider } from "@follow/components/ui/divider/index.js"
|
||||
import { LoadingCircle } from "@follow/components/ui/loading/index.jsx"
|
||||
import { ScrollArea } from "@follow/components/ui/scroll-area/index.js"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@follow/components/ui/table/index.jsx"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipPortal,
|
||||
TooltipTrigger,
|
||||
} from "@follow/components/ui/tooltip/index.jsx"
|
||||
import { Trans } from "react-i18next"
|
||||
import { Link } from "react-router"
|
||||
import { toast } from "sonner"
|
||||
|
||||
import { useAppMessagingToken } from "~/atoms/app"
|
||||
import { useCurrentModal } from "~/components/ui/modal/stacked/hooks"
|
||||
import { useI18n } from "~/hooks/common"
|
||||
import { useMessaging, useTestMessaging } from "~/queries/messaging"
|
||||
|
||||
export const SettingNotifications = () => {
|
||||
const t = useI18n()
|
||||
const { isLoading, data } = useMessaging()
|
||||
const { dismiss } = useCurrentModal()
|
||||
|
||||
const token = useAppMessagingToken()
|
||||
|
||||
const testMessaging = useTestMessaging()
|
||||
|
||||
return (
|
||||
<section className="mt-4">
|
||||
<div className="mb-4 space-y-2 text-sm">
|
||||
<p>
|
||||
<Trans
|
||||
ns="settings"
|
||||
i18nKey="notifications.info"
|
||||
components={{
|
||||
ActionsLink: (
|
||||
<Link
|
||||
className="underline"
|
||||
to="/action"
|
||||
onClick={() => {
|
||||
dismiss()
|
||||
}}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
<Divider className="mb-6 mt-8" />
|
||||
<div className="flex flex-1 flex-col">
|
||||
{isLoading && <LoadingCircle size="large" className="center absolute inset-0" />}
|
||||
|
||||
<ScrollArea.ScrollArea viewportClassName="max-h-[380px]">
|
||||
<div className="overflow-auto">
|
||||
<Table className="mt-4">
|
||||
<TableHeader>
|
||||
<TableRow className="[&_*]:!font-semibold">
|
||||
<TableHead size="sm">{t.settings("notifications.channel")}</TableHead>
|
||||
<TableHead size="sm">{t.settings("notifications.token")}</TableHead>
|
||||
<TableHead size="sm" className="center">
|
||||
{t.common("words.actions")}
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody className="border-t-[12px] border-transparent [&_td]:!px-3">
|
||||
{data?.data?.map((row) => (
|
||||
<TableRow key={row.channel} className="h-8">
|
||||
<TableCell size="sm">{row.channel}</TableCell>
|
||||
<TableCell size="sm" className="truncate">
|
||||
{row.token.slice(0, 6)}...{row.token.slice(-6)}
|
||||
{row.token === token && ` ${t.settings("notifications.current")}`}
|
||||
</TableCell>
|
||||
<TableCell size="sm" className="center">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
onClick={() =>
|
||||
testMessaging.mutate(
|
||||
{ channel: row.channel },
|
||||
{
|
||||
onSuccess: () => {
|
||||
toast.success(t.settings("notifications.test_success"))
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
>
|
||||
<i className="i-mgc-finger-press-cute-re" />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipPortal>
|
||||
<TooltipContent>{t.settings("notifications.test")}</TooltipContent>
|
||||
</TooltipPortal>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</ScrollArea.ScrollArea>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import { UserRole } from "@follow/constants"
|
||||
|
||||
import { SettingNotifications } from "~/modules/settings/tabs/notifications"
|
||||
import { SettingsTitle } from "~/modules/settings/title"
|
||||
import { defineSettingPageData, DisableWhy } from "~/modules/settings/utils"
|
||||
|
||||
const iconName = "i-mgc-notification-cute-re"
|
||||
const priority = 1040
|
||||
|
||||
export const loader = defineSettingPageData({
|
||||
icon: iconName,
|
||||
name: "titles.notifications",
|
||||
priority,
|
||||
disableIf: (ctx) => [ctx.role === UserRole.Trial, DisableWhy.NotActivation],
|
||||
})
|
||||
|
||||
export function Component() {
|
||||
return (
|
||||
<>
|
||||
<SettingsTitle />
|
||||
<SettingNotifications />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ import { env } from "@follow/shared/env.desktop"
|
|||
import { initializeApp } from "firebase/app"
|
||||
import { getMessaging, getToken } from "firebase/messaging"
|
||||
|
||||
import { setAppMessagingToken } from "./atoms/app"
|
||||
import { apiClient } from "./lib/api-fetch"
|
||||
import { router } from "./router"
|
||||
|
||||
|
|
@ -52,6 +53,8 @@ export async function registerWebPushNotifications() {
|
|||
|
||||
registerPushNotificationPostMessage()
|
||||
|
||||
setAppMessagingToken(token)
|
||||
|
||||
return token
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import { useMutation } from "@tanstack/react-query"
|
||||
|
||||
import { useAuthQuery } from "~/hooks/common"
|
||||
import { apiClient } from "~/lib/api-fetch"
|
||||
import { defineQuery } from "~/lib/defineQuery"
|
||||
|
||||
export const messaging = {
|
||||
list: () =>
|
||||
defineQuery(["messaging"], () => apiClient.messaging.$get(), {
|
||||
rootKey: ["messaging"],
|
||||
}),
|
||||
}
|
||||
|
||||
export const useMessaging = () => useAuthQuery(messaging.list())
|
||||
|
||||
export const useTestMessaging = () =>
|
||||
useMutation({
|
||||
mutationFn: ({ channel }: { channel: string }) =>
|
||||
apiClient.messaging.test.$get({
|
||||
query: {
|
||||
channel,
|
||||
},
|
||||
}),
|
||||
})
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
|
||||
interface BellRingingCuteFiIconProps {
|
||||
width?: number
|
||||
height?: number
|
||||
color?: string
|
||||
}
|
||||
|
||||
export const BellRingingCuteFiIcon = ({
|
||||
width = 24,
|
||||
height = 24,
|
||||
color = "#10161F",
|
||||
}: BellRingingCuteFiIconProps) => {
|
||||
return (
|
||||
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
|
||||
<Path
|
||||
d="M5.964 2.082c-.361.163-1.184.944-1.769 1.678-.587.737-1.136 1.654-1.18 1.971a.996.996 0 0 0 1.461 1.008c.224-.123.293-.21.634-.799.353-.609.671-1.003 1.374-1.702.388-.386.739-.764.78-.84.108-.202.102-.645-.013-.862a1.145 1.145 0 0 0-.517-.476c-.203-.085-.557-.075-.77.022m11.296.031c-.192.09-.39.286-.488.483-.099.197-.096.653.004.841.041.076.383.445.761.82.683.679 1 1.074 1.353 1.683.089.154.222.373.295.488.548.856 1.886.4 1.805-.615-.017-.209-.058-.316-.25-.661a10.234 10.234 0 0 0-1.864-2.406 7.313 7.313 0 0 0-.626-.535c-.201-.138-.246-.152-.525-.162-.233-.009-.343.006-.465.064m-6.056.933c-2.638.276-4.98 1.985-6.061 4.424-.503 1.133-.622 1.849-.623 3.716 0 2.243-.094 2.745-.755 4.034-.18.352-.364.756-.408.898-.363 1.178.268 2.411 1.421 2.773l.282.089h13.88l.282-.089c1.153-.362 1.784-1.595 1.421-2.773-.044-.142-.228-.546-.408-.898-.661-1.288-.755-1.792-.755-4.029 0-.984-.016-1.429-.062-1.746a7.351 7.351 0 0 0-.982-2.786 7.516 7.516 0 0 0-7.232-3.613M9.241 20.182a3.16 3.16 0 0 0 1.117 1.319c.54.349.982.478 1.642.478.255 0 .558-.024.68-.055a3.095 3.095 0 0 0 2.072-1.734l.084-.19H9.163l.078.182"
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
|
||||
interface BellRingingCuteReIconProps {
|
||||
width?: number
|
||||
height?: number
|
||||
color?: string
|
||||
}
|
||||
|
||||
export const BellRingingCuteReIcon = ({
|
||||
width = 24,
|
||||
height = 24,
|
||||
color = "#10161F",
|
||||
}: BellRingingCuteReIconProps) => {
|
||||
return (
|
||||
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
|
||||
<Path
|
||||
d="M17.221 2.082a1.064 1.064 0 0 0-.473.458c-.114.213-.12.657-.011.859.041.077.393.455.781.84.703.699 1.015 1.085 1.372 1.701.089.154.222.373.295.488.548.856 1.886.4 1.805-.615-.017-.209-.058-.315-.25-.659a9.53 9.53 0 0 0-.935-1.394c-.585-.734-1.408-1.515-1.769-1.678-.234-.107-.601-.106-.815 0M5.898 2.12c-.197.098-.781.604-1.15.996A10.507 10.507 0 0 0 3.197 5.27c-.152.292-.172.36-.17.585a.974.974 0 0 0 1.393.89c.256-.122.364-.241.626-.695.415-.718.706-1.085 1.436-1.812.557-.555.72-.742.777-.889.176-.461-.061-1.025-.519-1.234-.223-.102-.63-.1-.842.005m5.306.926a7.548 7.548 0 0 0-4.612 2.269C5.598 6.359 4.907 7.677 4.66 9a7.694 7.694 0 0 1-.087.42c-.012.044-.037.908-.054 1.92-.04 2.402-.054 2.469-.796 3.983-.481.981-.554 1.314-.423 1.937a2.225 2.225 0 0 0 1.457 1.628c.246.081.364.088 1.815.109l1.552.023.091.26c.287.813.844 1.556 1.5 1.998.373.252.939.507 1.347.609.509.126 1.367.126 1.876 0a4.848 4.848 0 0 0 1.347-.609c.656-.442 1.213-1.185 1.5-1.998l.091-.26 1.552-.023c1.451-.021 1.569-.028 1.815-.109A2.225 2.225 0 0 0 20.7 17.26c.133-.632.064-.928-.474-2.049-.704-1.466-.704-1.47-.747-3.871-.025-1.397-.047-1.916-.095-2.157-.191-.972-.488-1.76-.948-2.524a7.516 7.516 0 0 0-7.232-3.613m2.006 2.089a5.367 5.367 0 0 1 2.585 1.403 5.458 5.458 0 0 1 1.629 3.042c.051.279.073.764.096 2.16.029 1.727.035 1.82.134 2.284.144.67.292 1.071.729 1.976.208.429.377.797.377.817 0 .02-.03.07-.066.11-.064.07-.324.073-6.687.073-6.105 0-6.626-.005-6.694-.066-.04-.037-.073-.089-.073-.116 0-.027.17-.397.379-.821.397-.811.607-1.39.746-2.057.074-.354.087-.609.114-2.2.035-1.99.058-2.218.306-2.977.271-.83.728-1.55 1.392-2.196.869-.845 1.853-1.33 3.092-1.526.127-.02.519-.03.871-.021.503.011.732.036 1.07.115m.442 13.989c-.119.205-.516.544-.782.67-.764.36-1.612.233-2.22-.332a2.122 2.122 0 0 1-.302-.338L10.275 19h3.45l-.073.124"
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
|
||||
interface FireCuteReIconProps {
|
||||
width?: number
|
||||
height?: number
|
||||
color?: string
|
||||
}
|
||||
|
||||
export const FireCuteReIcon = ({
|
||||
width = 24,
|
||||
height = 24,
|
||||
color = "#10161F",
|
||||
}: FireCuteReIconProps) => {
|
||||
return (
|
||||
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
|
||||
<Path
|
||||
d="M11 2.771c-.682.247-1.043.641-1.422 1.553-.66 1.59-1.744 3.07-3.247 4.436-1.351 1.227-2.122 2.184-2.711 3.37-.816 1.642-.988 3.211-.525 4.793.648 2.213 2.547 4.052 4.934 4.78.394.12.517.141.751.128a1.454 1.454 0 0 0 1.252-.862c.154-.331.151-.814-.006-1.289-.399-1.205-.264-2.124.449-3.068.246-.326.98-1.052 1.063-1.052.024 0 .124.129.223.286.098.158.392.576.652.93.489.666.7 1.045.792 1.424.076.318.067 1.133-.02 1.76-.072.511-.072.554-.009.799a1.48 1.48 0 0 0 1.224 1.124c.289.047.624-.004 1.46-.222 1.381-.36 2.464-.97 3.329-1.876 1.074-1.123 1.621-2.508 1.774-4.485.134-1.732-.214-3.256-1.182-5.181a17.995 17.995 0 0 0-1.106-1.888c-.327-.489-.937-1.291-1.124-1.479a1.779 1.779 0 0 0-2.071-.313 1.465 1.465 0 0 0-.251.153c-.09.079-.115.05-.226-.272-.144-.413-.533-1.187-.802-1.597a7.477 7.477 0 0 0-1.091-1.331c-.305-.303-.46-.422-.698-.54-.288-.142-.332-.152-.729-.163-.362-.01-.46.002-.683.082m.918 2.259c.619.675 1.012 1.375 1.342 2.391.241.743.35.951.659 1.262.259.26.569.423.908.478.527.085 1.091-.155 1.359-.579a.847.847 0 0 1 .134-.179c.028 0 .468.594.712.962.948 1.423 1.595 2.837 1.849 4.04.162.772.146 1.891-.04 2.775-.314 1.487-1.025 2.455-2.274 3.094-.316.161-1.195.486-1.316.486-.017 0-.02-.193-.006-.43.05-.844-.059-1.63-.313-2.25-.182-.444-.335-.695-.867-1.419a18.193 18.193 0 0 1-.656-.948c-.367-.597-.888-1.001-1.438-1.115a3.002 3.002 0 0 0-.594-.031c-.326.014-.402.033-.666.164-.373.184-1.066.772-1.497 1.27-.717.83-1.115 1.584-1.318 2.499-.082.372-.098 1.522-.025 1.819a.595.595 0 0 1 .03.194c-.028.027-.577-.28-.888-.496-.886-.617-1.58-1.47-1.893-2.327-.442-1.208-.36-2.349.26-3.63.401-.829.877-1.452 1.756-2.3 1.836-1.771 2.375-2.376 3.124-3.5.549-.824.957-1.598 1.239-2.35.04-.104.086-.19.103-.19s.16.139.316.31"
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
import * as React from "react"
|
||||
import Svg, { Path } from "react-native-svg"
|
||||
|
||||
interface NotificationCuteReIconProps {
|
||||
width?: number
|
||||
height?: number
|
||||
color?: string
|
||||
}
|
||||
|
||||
export const NotificationCuteReIcon = ({
|
||||
width = 24,
|
||||
height = 24,
|
||||
color = "#10161F",
|
||||
}: NotificationCuteReIconProps) => {
|
||||
return (
|
||||
<Svg width={width} height={height} fill="none" viewBox="0 0 24 24">
|
||||
<Path
|
||||
d="M11.204 2.043A7.587 7.587 0 0 0 5.993 5.02a7.874 7.874 0 0 0-1.239 2.554c-.19.731-.201.862-.235 2.766-.042 2.377-.053 2.432-.738 3.86-.433.9-.485 1.043-.521 1.422-.037.388.031.738.219 1.131.273.567.743.965 1.382 1.169.111.035.628.058 1.712.074l1.553.024.094.268a4.044 4.044 0 0 0 1.94 2.248c.451.231.77.335 1.235.406.484.072.726.072 1.21 0a4.015 4.015 0 0 0 3.175-2.654l.094-.268 1.553-.024c1.084-.016 1.601-.039 1.712-.074.639-.204 1.109-.602 1.382-1.169.188-.393.256-.743.219-1.131-.036-.376-.088-.517-.522-1.422-.682-1.423-.7-1.516-.739-3.88-.032-1.886-.043-2.013-.233-2.746-.228-.88-.709-1.854-1.3-2.633-.318-.42-1.004-1.104-1.406-1.402-1.008-.747-2.088-1.219-3.26-1.423-.536-.093-1.574-.13-2.076-.073m1.576 2.016c1.99.289 3.716 1.689 4.379 3.551.294.828.323 1.076.359 3.11.034 1.894.048 2.041.267 2.808.136.477.326.936.677 1.636.164.327.298.621.298.653 0 .031-.028.086-.063.12-.056.057-.719.063-6.697.063s-6.641-.006-6.697-.063c-.035-.034-.063-.089-.063-.12 0-.032.134-.326.298-.653.351-.7.541-1.159.677-1.636.219-.767.233-.914.267-2.808.017-.99.051-1.895.077-2.04.219-1.253.688-2.169 1.559-3.043.731-.734 1.463-1.166 2.442-1.442a5.559 5.559 0 0 1 2.22-.136m.94 13.982c0 .022-.13.173-.29.335-.309.313-.566.467-.938.564a2.073 2.073 0 0 1-1.423-.165c-.2-.101-.789-.649-.789-.734 0-.027.578-.041 1.72-.041s1.72.014 1.72.041"
|
||||
fill={color}
|
||||
fillRule="evenodd"
|
||||
/>
|
||||
</Svg>
|
||||
)
|
||||
}
|
||||
|
|
@ -14,12 +14,12 @@ import {
|
|||
GroupedInsetListNavigationLinkIcon,
|
||||
} from "@/src/components/ui/grouped/GroupedList"
|
||||
import { getDbPath } from "@/src/database"
|
||||
import { BellRingingCuteFiIcon } from "@/src/icons/bell_ringing_cute_fi"
|
||||
import { CertificateCuteFiIcon } from "@/src/icons/certificate_cute_fi"
|
||||
import { DatabaseIcon } from "@/src/icons/database"
|
||||
import { ExitCuteFiIcon } from "@/src/icons/exit_cute_fi"
|
||||
import { LoveCuteFiIcon } from "@/src/icons/love_cute_fi"
|
||||
import { Magic2CuteFiIcon } from "@/src/icons/magic_2_cute_fi"
|
||||
import { NotificationCuteReIcon } from "@/src/icons/notification_cute_re"
|
||||
import { PaletteCuteFiIcon } from "@/src/icons/palette_cute_fi"
|
||||
import { RadaCuteFiIcon } from "@/src/icons/rada_cute_fi"
|
||||
import { SafeLockFilledIcon } from "@/src/icons/safe_lock_filled"
|
||||
|
|
@ -66,7 +66,7 @@ const SettingGroupNavigationLinks: GroupNavigationLink[] = [
|
|||
},
|
||||
{
|
||||
label: "titles.notifications",
|
||||
icon: BellRingingCuteFiIcon,
|
||||
icon: NotificationCuteReIcon,
|
||||
onPress: ({ navigation }) => {
|
||||
navigation.pushControllerView(NotificationsScreen)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M5.964 2.082c-.361.163-1.184.944-1.769 1.678-.587.737-1.136 1.654-1.18 1.971a.996.996 0 0 0 1.461 1.008c.224-.123.293-.21.634-.799.353-.609.671-1.003 1.374-1.702.388-.386.739-.764.78-.84.108-.202.102-.645-.013-.862a1.145 1.145 0 0 0-.517-.476c-.203-.085-.557-.075-.77.022m11.296.031c-.192.09-.39.286-.488.483-.099.197-.096.653.004.841.041.076.383.445.761.82.683.679 1 1.074 1.353 1.683.089.154.222.373.295.488.548.856 1.886.4 1.805-.615-.017-.209-.058-.316-.25-.661a10.234 10.234 0 0 0-1.864-2.406 7.313 7.313 0 0 0-.626-.535c-.201-.138-.246-.152-.525-.162-.233-.009-.343.006-.465.064m-6.056.933c-2.638.276-4.98 1.985-6.061 4.424-.503 1.133-.622 1.849-.623 3.716 0 2.243-.094 2.745-.755 4.034-.18.352-.364.756-.408.898-.363 1.178.268 2.411 1.421 2.773l.282.089h13.88l.282-.089c1.153-.362 1.784-1.595 1.421-2.773-.044-.142-.228-.546-.408-.898-.661-1.288-.755-1.792-.755-4.029 0-.984-.016-1.429-.062-1.746a7.351 7.351 0 0 0-.982-2.786 7.516 7.516 0 0 0-7.232-3.613M9.241 20.182a3.16 3.16 0 0 0 1.117 1.319c.54.349.982.478 1.642.478.255 0 .558-.024.68-.055a3.095 3.095 0 0 0 2.072-1.734l.084-.19H9.163l.078.182" fill="#10161F" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M17.221 2.082a1.064 1.064 0 0 0-.473.458c-.114.213-.12.657-.011.859.041.077.393.455.781.84.703.699 1.015 1.085 1.372 1.701.089.154.222.373.295.488.548.856 1.886.4 1.805-.615-.017-.209-.058-.315-.25-.659a9.53 9.53 0 0 0-.935-1.394c-.585-.734-1.408-1.515-1.769-1.678-.234-.107-.601-.106-.815 0M5.898 2.12c-.197.098-.781.604-1.15.996A10.507 10.507 0 0 0 3.197 5.27c-.152.292-.172.36-.17.585a.974.974 0 0 0 1.393.89c.256-.122.364-.241.626-.695.415-.718.706-1.085 1.436-1.812.557-.555.72-.742.777-.889.176-.461-.061-1.025-.519-1.234-.223-.102-.63-.1-.842.005m5.306.926a7.548 7.548 0 0 0-4.612 2.269C5.598 6.359 4.907 7.677 4.66 9a7.694 7.694 0 0 1-.087.42c-.012.044-.037.908-.054 1.92-.04 2.402-.054 2.469-.796 3.983-.481.981-.554 1.314-.423 1.937a2.225 2.225 0 0 0 1.457 1.628c.246.081.364.088 1.815.109l1.552.023.091.26c.287.813.844 1.556 1.5 1.998.373.252.939.507 1.347.609.509.126 1.367.126 1.876 0a4.848 4.848 0 0 0 1.347-.609c.656-.442 1.213-1.185 1.5-1.998l.091-.26 1.552-.023c1.451-.021 1.569-.028 1.815-.109A2.225 2.225 0 0 0 20.7 17.26c.133-.632.064-.928-.474-2.049-.704-1.466-.704-1.47-.747-3.871-.025-1.397-.047-1.916-.095-2.157-.191-.972-.488-1.76-.948-2.524a7.516 7.516 0 0 0-7.232-3.613m2.006 2.089a5.367 5.367 0 0 1 2.585 1.403 5.458 5.458 0 0 1 1.629 3.042c.051.279.073.764.096 2.16.029 1.727.035 1.82.134 2.284.144.67.292 1.071.729 1.976.208.429.377.797.377.817 0 .02-.03.07-.066.11-.064.07-.324.073-6.687.073-6.105 0-6.626-.005-6.694-.066-.04-.037-.073-.089-.073-.116 0-.027.17-.397.379-.821.397-.811.607-1.39.746-2.057.074-.354.087-.609.114-2.2.035-1.99.058-2.218.306-2.977.271-.83.728-1.55 1.392-2.196.869-.845 1.853-1.33 3.092-1.526.127-.02.519-.03.871-.021.503.011.732.036 1.07.115m.442 13.989c-.119.205-.516.544-.782.67-.764.36-1.612.233-2.22-.332a2.122 2.122 0 0 1-.302-.338L10.275 19h3.45l-.073.124" fill="#10161F" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.9 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M9.814 2.041c-1.483.156-2.819.8-3.896 1.877-1.911 1.911-2.434 4.653-1.368 7.18.134.319.23.484.35.604a.984.984 0 0 0 1.405-.005c.198-.198.316-.527.285-.793a3.004 3.004 0 0 0-.187-.555 4.555 4.555 0 0 1-.392-1.652c-.132-2.844 2.43-5.113 5.232-4.632A4.506 4.506 0 0 1 14.88 9.52c-.13.571-.064.89.246 1.188.184.176.388.252.674.252.285 0 .45-.061.655-.241.185-.163.275-.338.358-.699a6.456 6.456 0 0 0-.156-3.574c-.543-1.636-1.782-3.051-3.317-3.787a6.61 6.61 0 0 0-3.526-.618m.146 4.021c-.837.179-1.557.843-1.855 1.711-.083.241-.085.319-.105 3.458l-.02 3.21-.28-.206c-.325-.239-.895-.521-1.24-.613a3.552 3.552 0 0 0-1.367-.047c-.876.153-1.361.507-1.617 1.181-.107.282-.143.82-.077 1.14.06.289 2.688 5.578 2.88 5.797a.984.984 0 0 0 1.201.203c.347-.189.52-.486.52-.894 0-.235-.026-.293-1.3-2.841-.715-1.431-1.3-2.611-1.3-2.621 0-.047.454-.014.628.045.455.154 1.085.711 1.881 1.663.336.402.503.57.63.631.411.2.86.128 1.164-.184.316-.325.297-.014.297-4.924 0-4.83-.016-4.529.252-4.693a.451.451 0 0 1 .496 0c.261.159.252.066.252 2.753 0 1.576.015 2.518.043 2.672.122.667.64 1.27 1.288 1.497.141.05 1.098.193 2.654.398 1.729.228 2.505.346 2.675.407a1.971 1.971 0 0 1 1.279 1.413c.079.309.079 1.076.001 1.602a5.958 5.958 0 0 1-.412 1.5c-.236.578-.25.822-.068 1.154a.99.99 0 0 0 1.43.344c.201-.133.321-.326.535-.858.396-.985.547-1.807.552-3 .003-.776-.006-.895-.09-1.22a4.822 4.822 0 0 0-.784-1.57 4.095 4.095 0 0 0-2.343-1.407 145.83 145.83 0 0 0-2.38-.323 191.702 191.702 0 0 1-2.27-.304l-.11-.022-.001-2.427c0-2.739-.002-2.759-.288-3.326-.502-.997-1.642-1.536-2.751-1.299" fill="#10161F" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M11.204 2.043A7.587 7.587 0 0 0 5.993 5.02a7.874 7.874 0 0 0-1.239 2.554c-.19.731-.201.862-.235 2.766-.042 2.377-.053 2.432-.738 3.86-.433.9-.485 1.043-.521 1.422-.037.388.031.738.219 1.131.273.567.743.965 1.382 1.169.111.035.628.058 1.712.074l1.553.024.094.268a4.044 4.044 0 0 0 1.94 2.248c.451.231.77.335 1.235.406.484.072.726.072 1.21 0a4.015 4.015 0 0 0 3.175-2.654l.094-.268 1.553-.024c1.084-.016 1.601-.039 1.712-.074.639-.204 1.109-.602 1.382-1.169.188-.393.256-.743.219-1.131-.036-.376-.088-.517-.522-1.422-.682-1.423-.7-1.516-.739-3.88-.032-1.886-.043-2.013-.233-2.746-.228-.88-.709-1.854-1.3-2.633-.318-.42-1.004-1.104-1.406-1.402-1.008-.747-2.088-1.219-3.26-1.423-.536-.093-1.574-.13-2.076-.073m1.576 2.016c1.99.289 3.716 1.689 4.379 3.551.294.828.323 1.076.359 3.11.034 1.894.048 2.041.267 2.808.136.477.326.936.677 1.636.164.327.298.621.298.653 0 .031-.028.086-.063.12-.056.057-.719.063-6.697.063s-6.641-.006-6.697-.063c-.035-.034-.063-.089-.063-.12 0-.032.134-.326.298-.653.351-.7.541-1.159.677-1.636.219-.767.233-.914.267-2.808.017-.99.051-1.895.077-2.04.219-1.253.688-2.169 1.559-3.043.731-.734 1.463-1.166 2.442-1.442a5.559 5.559 0 0 1 2.22-.136m.94 13.982c0 .022-.13.173-.29.335-.309.313-.566.467-.938.564a2.073 2.073 0 0 1-1.423-.165c-.2-.101-.789-.649-.789-.734 0-.027.578-.041 1.72-.041s1.72.014 1.72.041" fill="#10161F" fill-rule="evenodd"/></svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -342,6 +342,12 @@
|
|||
"lists.subscriptions": "Subs",
|
||||
"lists.title": "Title",
|
||||
"lists.view": "View",
|
||||
"notifications.channel": "Channel",
|
||||
"notifications.current": "(current client)",
|
||||
"notifications.info": "Folo offers robust and versatile notification features through <ActionsLink>Actions</ActionsLink>. You can customize notification for specific feeds, views, or keywords. Below are your registered notification channels.",
|
||||
"notifications.test": "Test Notification",
|
||||
"notifications.test_success": "Test notification sent successfully.",
|
||||
"notifications.token": "Client Token",
|
||||
"privacy.privacy": "Privacy",
|
||||
"privacy.terms": "Terms",
|
||||
"profile.avatar.label": "Avatar",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue