mirror of
https://github.com/Athou/commafeed.git
synced 2026-11-05 03:44:47 +00:00
move handlers in Layout because they actually only apply to the reader pages
This commit is contained in:
@@ -4,21 +4,16 @@ import { MantineProvider, v8CssVariablesResolver } from "@mantine/core"
|
||||
import { ModalsProvider } from "@mantine/modals"
|
||||
import { Notifications } from "@mantine/notifications"
|
||||
import type React from "react"
|
||||
import { useEffect, useState } from "react"
|
||||
import { useEffect } from "react"
|
||||
import { HashRouter, Navigate, Route, Routes, useNavigate } from "react-router-dom"
|
||||
import Tinycon from "tinycon"
|
||||
import { Constants } from "@/app/constants"
|
||||
import { redirectTo } from "@/app/redirect/slice"
|
||||
import { redirectToInitialSetup } from "@/app/redirect/thunks"
|
||||
import { reloadServerInfos } from "@/app/server/thunks"
|
||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||
import { categoryUnreadCount } from "@/app/utils"
|
||||
import { DisablePullToRefresh } from "@/components/DisablePullToRefresh"
|
||||
import { ErrorBoundary } from "@/components/ErrorBoundary"
|
||||
import { Header } from "@/components/header/Header"
|
||||
import { Tree } from "@/components/sidebar/Tree"
|
||||
import { useAppLoading } from "@/hooks/useAppLoading"
|
||||
import { useBrowserExtension } from "@/hooks/useBrowserExtension"
|
||||
import { useI18n } from "@/i18n"
|
||||
import { AdminUsersPage } from "@/pages/admin/AdminUsersPage"
|
||||
import { MetricsPage } from "@/pages/admin/MetricsPage"
|
||||
@@ -146,83 +141,8 @@ function RedirectHandler() {
|
||||
return null
|
||||
}
|
||||
|
||||
function UnreadCountTitleHandler({
|
||||
enabled,
|
||||
}: Readonly<{
|
||||
enabled?: boolean
|
||||
}>) {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
|
||||
}
|
||||
|
||||
function UnreadCountFaviconHandler({ enabled }: { enabled?: boolean }) {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
useEffect(() => {
|
||||
if (enabled && unreadCount > 0) {
|
||||
Tinycon.setBubble(unreadCount)
|
||||
} else {
|
||||
Tinycon.reset()
|
||||
}
|
||||
}, [unreadCount, enabled])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function BrowserExtensionBadgeUnreadCountHandler() {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const { setBadgeUnreadCount } = useBrowserExtension()
|
||||
useEffect(() => {
|
||||
if (!root) return
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
setBadgeUnreadCount(unreadCount)
|
||||
}, [root, setBadgeUnreadCount])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function CustomJsHandler() {
|
||||
const [scriptLoaded, setScriptLoaded] = useState(false)
|
||||
const { loading } = useAppLoading()
|
||||
|
||||
useEffect(() => {
|
||||
if (scriptLoaded || loading) {
|
||||
return
|
||||
}
|
||||
|
||||
const script = document.createElement("script")
|
||||
script.src = "custom_js.js"
|
||||
script.async = true
|
||||
document.body.appendChild(script)
|
||||
|
||||
setScriptLoaded(true)
|
||||
|
||||
return () => script.remove()
|
||||
}, [scriptLoaded, loading])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function CustomCssHandler() {
|
||||
useEffect(() => {
|
||||
const link = document.createElement("link")
|
||||
link.rel = "stylesheet"
|
||||
link.type = "text/css"
|
||||
link.href = "custom_css.css"
|
||||
document.head.appendChild(link)
|
||||
|
||||
return () => link.remove()
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
export function App() {
|
||||
useI18n()
|
||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
||||
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
||||
const dispatch = useAppDispatch()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -231,13 +151,6 @@ export function App() {
|
||||
|
||||
return (
|
||||
<Providers>
|
||||
<UnreadCountTitleHandler enabled={unreadCountTitle} />
|
||||
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
|
||||
<BrowserExtensionBadgeUnreadCountHandler />
|
||||
<CustomJsHandler />
|
||||
<CustomCssHandler />
|
||||
<DisablePullToRefresh enabled={disablePullToRefresh} />
|
||||
|
||||
<HashRouter>
|
||||
<InitialSetupHandler />
|
||||
<RedirectHandler />
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { msg } from "@lingui/core/macro"
|
||||
import { ActionIcon, AppShell, Box, Center, Group, ScrollArea, Title, useMantineTheme } from "@mantine/core"
|
||||
import { type ReactNode, type RefObject, Suspense, useEffect, useRef } from "react"
|
||||
import { type ReactNode, type RefObject, Suspense, useEffect, useRef, useState } from "react"
|
||||
import Draggable from "react-draggable"
|
||||
import { TbMenu2, TbPlus, TbX } from "react-icons/tb"
|
||||
import { Outlet } from "react-router-dom"
|
||||
import { useSwipeable } from "react-swipeable"
|
||||
import Tinycon from "tinycon"
|
||||
import { Constants } from "@/app/constants"
|
||||
import { redirectToAdd, redirectToRootCategory } from "@/app/redirect/thunks"
|
||||
import { useAppDispatch, useAppSelector } from "@/app/store"
|
||||
@@ -12,8 +13,10 @@ import { setMobileMenuOpen } from "@/app/tree/slice"
|
||||
import { reloadTree } from "@/app/tree/thunks"
|
||||
import { setSidebarWidth } from "@/app/user/slice"
|
||||
import { reloadProfile, reloadSettings, reloadTags } from "@/app/user/thunks"
|
||||
import { categoryUnreadCount } from "@/app/utils"
|
||||
import { ActionButton } from "@/components/ActionButton"
|
||||
import { AnnouncementDialog } from "@/components/AnnouncementDialog"
|
||||
import { DisablePullToRefresh } from "@/components/DisablePullToRefresh"
|
||||
import { Loader } from "@/components/Loader"
|
||||
import { Logo } from "@/components/Logo"
|
||||
import { MarkAllAsReadConfirmationDialog } from "@/components/MarkAllAsReadConfirmationDialog"
|
||||
@@ -51,6 +54,78 @@ function LogoAndTitle() {
|
||||
)
|
||||
}
|
||||
|
||||
function UnreadCountTitleHandler({
|
||||
enabled,
|
||||
}: Readonly<{
|
||||
enabled?: boolean
|
||||
}>) {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
return <title>{enabled && unreadCount > 0 ? `(${unreadCount}) CommaFeed` : "CommaFeed"}</title>
|
||||
}
|
||||
|
||||
function UnreadCountFaviconHandler({ enabled }: { enabled?: boolean }) {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
useEffect(() => {
|
||||
if (enabled && unreadCount > 0) {
|
||||
Tinycon.setBubble(unreadCount)
|
||||
} else {
|
||||
Tinycon.reset()
|
||||
}
|
||||
}, [unreadCount, enabled])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function BrowserExtensionBadgeUnreadCountHandler() {
|
||||
const root = useAppSelector(state => state.tree.rootCategory)
|
||||
const { setBadgeUnreadCount } = useBrowserExtension()
|
||||
useEffect(() => {
|
||||
if (!root) return
|
||||
const unreadCount = categoryUnreadCount(root)
|
||||
setBadgeUnreadCount(unreadCount)
|
||||
}, [root, setBadgeUnreadCount])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function CustomJsHandler() {
|
||||
const [scriptLoaded, setScriptLoaded] = useState(false)
|
||||
const { loading } = useAppLoading()
|
||||
|
||||
useEffect(() => {
|
||||
if (scriptLoaded || loading) {
|
||||
return
|
||||
}
|
||||
|
||||
const script = document.createElement("script")
|
||||
script.src = "custom_js.js"
|
||||
script.async = true
|
||||
document.body.appendChild(script)
|
||||
|
||||
setScriptLoaded(true)
|
||||
|
||||
return () => script.remove()
|
||||
}, [scriptLoaded, loading])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
function CustomCssHandler() {
|
||||
useEffect(() => {
|
||||
const link = document.createElement("link")
|
||||
link.rel = "stylesheet"
|
||||
link.type = "text/css"
|
||||
link.href = "custom_css.css"
|
||||
document.head.appendChild(link)
|
||||
|
||||
return () => link.remove()
|
||||
}, [])
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
const useStyles = tss
|
||||
.withParams<{
|
||||
sidebarWidth: number
|
||||
@@ -75,6 +150,9 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
||||
const draggableSeparator = useRef<HTMLDivElement>(null)
|
||||
|
||||
const { loading } = useAppLoading()
|
||||
const unreadCountTitle = useAppSelector(state => state.user.settings?.unreadCountTitle)
|
||||
const unreadCountFavicon = useAppSelector(state => state.user.settings?.unreadCountFavicon)
|
||||
const disablePullToRefresh = useAppSelector(state => state.user.settings?.disablePullToRefresh)
|
||||
const mobileMenuOpen = useAppSelector(state => state.tree.mobileMenuOpen)
|
||||
const webSocketConnected = useAppSelector(state => state.server.webSocketConnected)
|
||||
const treeReloadInterval = useAppSelector(state => state.server.serverInfos?.treeReloadInterval)
|
||||
@@ -173,6 +251,13 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
||||
|
||||
if (loading) return <LoadingPage />
|
||||
return (
|
||||
<>
|
||||
<UnreadCountTitleHandler enabled={unreadCountTitle} />
|
||||
<UnreadCountFaviconHandler enabled={unreadCountFavicon} />
|
||||
<BrowserExtensionBadgeUnreadCountHandler />
|
||||
<CustomJsHandler />
|
||||
<CustomCssHandler />
|
||||
<DisablePullToRefresh enabled={disablePullToRefresh} />
|
||||
<Box {...swipeHandlers}>
|
||||
<AppShell
|
||||
header={{ height: Constants.layout.headerHeight, collapsed: headerInFooter }}
|
||||
@@ -229,5 +314,6 @@ export default function Layout(props: Readonly<LayoutProps>) {
|
||||
</AppShell.Main>
|
||||
</AppShell>
|
||||
</Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user