2022-09-08 11:47:21 +03:00
/* eslint-disable react/no-array-index-key */
2022-09-26 12:04:37 +03:00
import useSWR , { SWRConfig } from "swr" ;
2022-08-24 10:44:35 +03:00
import Head from "next/head" ;
import dynamic from "next/dynamic" ;
2022-09-30 22:13:37 +03:00
import classNames from "classnames" ;
2022-09-25 19:43:00 +03:00
import { useTranslation } from "next-i18next" ;
2023-09-03 07:22:00 -07:00
import { useEffect , useContext , useState , useMemo } from "react" ;
2022-09-18 16:41:01 +03:00
import { BiError } from "react-icons/bi" ;
2022-09-25 19:43:00 +03:00
import { serverSideTranslations } from "next-i18next/serverSideTranslations" ;
2023-09-14 22:55:14 +01:00
import { useRouter } from "next/router" ;
2022-08-24 10:44:35 +03:00
2023-09-15 08:17:57 -07:00
import Tab , { slugify } from "components/tab" ;
2023-09-10 23:36:54 +02:00
import FileContent from "components/filecontent" ;
2022-08-24 10:44:35 +03:00
import ServicesGroup from "components/services/group" ;
import BookmarksGroup from "components/bookmarks/group" ;
2022-09-26 15:25:10 +03:00
import Widget from "components/widgets/widget" ;
import Revalidate from "components/toggles/revalidate" ;
2022-09-21 23:37:17 -07:00
import createLogger from "utils/logger" ;
2022-09-30 22:13:37 +03:00
import useWindowFocus from "utils/hooks/window-focus" ;
2022-09-26 15:25:10 +03:00
import { getSettings } from "utils/config/config" ;
2022-09-26 12:04:37 +03:00
import { ColorContext } from "utils/contexts/color" ;
import { ThemeContext } from "utils/contexts/theme" ;
import { SettingsContext } from "utils/contexts/settings" ;
2023-09-14 22:55:14 +01:00
import { TabContext } from "utils/contexts/tab" ;
2022-09-26 12:04:37 +03:00
import { bookmarksResponse , servicesResponse , widgetsResponse } from "utils/config/api-response" ;
2022-10-05 13:43:22 +03:00
import ErrorBoundary from "components/errorboundry" ;
2022-10-08 16:04:24 +03:00
import themes from "utils/styles/themes" ;
2022-10-19 13:55:18 -07:00
import QuickLaunch from "components/quicklaunch" ;
2023-01-31 00:25:23 -08:00
import { getStoredProvider , searchProviders } from "components/widgets/search/search" ;
2022-08-24 10:44:35 +03:00
2022-09-26 15:25:10 +03:00
const ThemeToggle = dynamic ( ( ) => import ( "components/toggles/theme" ) , {
2022-08-24 10:44:35 +03:00
ssr : false ,
} ) ;
2022-09-26 15:25:10 +03:00
const ColorToggle = dynamic ( ( ) => import ( "components/toggles/color" ) , {
2022-08-25 11:14:17 +03:00
ssr : false ,
} ) ;
2022-09-24 01:18:37 +03:00
const Version = dynamic ( ( ) => import ( "components/version" ) , {
ssr : false ,
} ) ;
2022-10-30 08:18:02 -07:00
const rightAlignedWidgets = [ "weatherapi" , "openweathermap" , "weather" , "openmeteo" , "search" , "datetime" ] ;
2022-08-27 15:26:00 +03:00
2022-09-25 19:43:00 +03:00
export async function getStaticProps ( ) {
2022-09-21 23:37:17 -07:00
let logger ;
2022-09-18 16:41:01 +03:00
try {
2022-09-24 01:18:37 +03:00
logger = createLogger ( "index" ) ;
2022-09-21 09:00:57 +03:00
const { providers , ... settings } = getSettings ( ) ;
2022-09-26 12:04:37 +03:00
const services = await servicesResponse ( ) ;
const bookmarks = await bookmarksResponse ( ) ;
const widgets = await widgetsResponse ( ) ;
2022-09-18 16:41:01 +03:00
return {
props : {
2022-09-21 09:00:57 +03:00
initialSettings : settings ,
2022-09-26 12:04:37 +03:00
fallback : {
2023-10-18 11:44:26 -07:00
"/api/services" : services ,
"/api/bookmarks" : bookmarks ,
"/api/widgets" : widgets ,
"/api/hash" : false ,
2022-09-26 12:04:37 +03:00
} ,
2022-09-25 19:43:00 +03:00
... ( await serverSideTranslations ( settings . language ? ? "en" ) ) ,
2022-09-18 16:41:01 +03:00
} ,
} ;
} catch ( e ) {
2022-09-24 01:18:37 +03:00
if ( logger ) {
logger . error ( e ) ;
}
2022-09-18 16:41:01 +03:00
return {
props : {
2022-09-21 09:00:57 +03:00
initialSettings : { } ,
2022-09-28 22:40:54 +03:00
fallback : {
2023-10-18 11:44:26 -07:00
"/api/services" : [ ] ,
"/api/bookmarks" : [ ] ,
"/api/widgets" : [ ] ,
"/api/hash" : false ,
2022-09-28 22:40:54 +03:00
} ,
2022-09-25 19:43:00 +03:00
... ( await serverSideTranslations ( "en" ) ) ,
2022-09-18 16:41:01 +03:00
} ,
} ;
}
}
2022-09-30 22:13:37 +03:00
function Index ( { initialSettings , fallback } ) {
2022-09-26 22:54:12 +03:00
const windowFocused = useWindowFocus ( ) ;
const [ stale , setStale ] = useState ( false ) ;
2023-10-18 11:44:26 -07:00
const { data : errorsData } = useSWR ( "/api/validate" ) ;
const { data : hashData , mutate : mutateHash } = useSWR ( "/api/hash" ) ;
2022-09-26 22:54:12 +03:00
useEffect ( ( ) => {
if ( windowFocused ) {
mutateHash ( ) ;
}
} , [ windowFocused , mutateHash ] ) ;
useEffect ( ( ) => {
if ( hashData ) {
if ( typeof window !== "undefined" ) {
const previousHash = localStorage . getItem ( "hash" ) ;
if ( ! previousHash ) {
localStorage . setItem ( "hash" , hashData . hash ) ;
}
2023-02-08 00:19:33 -08:00
if ( previousHash && previousHash !== hashData . hash ) {
2022-09-26 22:54:12 +03:00
setStale ( true ) ;
localStorage . setItem ( "hash" , hashData . hash ) ;
2023-10-18 11:44:26 -07:00
fetch ( "/api/revalidate" ) . then ( ( res ) => {
2022-09-26 22:54:12 +03:00
if ( res . ok ) {
window . location . reload ( ) ;
}
} ) ;
}
}
}
2023-02-08 00:19:33 -08:00
} , [ hashData ] ) ;
2022-09-26 22:54:12 +03:00
if ( stale ) {
return (
< div className = "flex items-center justify-center h-screen" >
< div className = "w-24 h-24 border-2 border-theme-400 border-solid rounded-full animate-spin border-t-transparent" / >
< / div >
) ;
}
2022-09-18 16:41:01 +03:00
if ( errorsData && errorsData . length > 0 ) {
return (
2022-09-30 22:13:37 +03:00
< div className = "w-full h-screen container m-auto justify-center p-10 pointer-events-none" >
2022-09-18 16:41:01 +03:00
< div className = "flex flex-col" >
{ errorsData . map ( ( error , i ) => (
< div
className = "basis-1/2 bg-theme-500 dark:bg-theme-600 text-theme-600 dark:text-theme-300 m-2 rounded-md font-mono shadow-md border-4 border-transparent"
key = { i }
>
< div className = "bg-amber-200 text-amber-800 dark:text-amber-200 dark:bg-amber-800 p-2 rounded-md font-bold" >
< BiError className = "float-right w-6 h-6" / >
{ error . config }
< / div >
< div className = "p-2 text-theme-100 dark:text-theme-200" >
< pre className = "opacity-50 font-bold pb-2" > { error . reason } < / pre >
< pre className = "text-sm" > { error . mark . snippet } < / pre >
< / div >
< / div >
) ) }
< / div >
< / div >
) ;
}
2022-09-09 06:45:43 +03:00
2022-09-26 12:04:37 +03:00
return (
< SWRConfig value = { { fallback , fetcher : ( resource , init ) => fetch ( resource , init ) . then ( ( res ) => res . json ( ) ) } } >
2022-10-05 13:43:22 +03:00
< ErrorBoundary >
< Home initialSettings = { initialSettings } / >
< / ErrorBoundary >
2022-09-26 12:04:37 +03:00
< / SWRConfig >
) ;
2022-09-09 06:45:43 +03:00
}
2022-09-15 05:17:30 +03:00
2022-10-08 16:40:36 +03:00
const headerStyles = {
boxed :
2023-09-16 02:37:24 -07:00
"m-6 mb-0 sm:m-9 sm:mb-0 rounded-md shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 dark:bg-white/5 p-3" ,
underlined : "m-6 mb-0 sm:m-9 sm:mb-1 border-b-2 pb-4 border-theme-800 dark:border-theme-200/50" ,
clean : "m-6 mb-0 sm:m-9 sm:mb-0" ,
boxedWidgets : "m-6 mb-0 sm:m-9 sm:mb-0 sm:mt-1" ,
2022-10-08 16:40:36 +03:00
} ;
2022-09-21 09:00:57 +03:00
function Home ( { initialSettings } ) {
2022-09-15 05:17:30 +03:00
const { i18n } = useTranslation ( ) ;
2022-09-15 19:58:41 +03:00
const { theme , setTheme } = useContext ( ThemeContext ) ;
const { color , setColor } = useContext ( ColorContext ) ;
2022-09-21 09:00:57 +03:00
const { settings , setSettings } = useContext ( SettingsContext ) ;
2023-09-14 22:55:14 +01:00
const { activeTab , setActiveTab } = useContext ( TabContext ) ;
const { asPath } = useRouter ( ) ;
2022-09-21 09:00:57 +03:00
2022-09-21 17:39:46 +03:00
useEffect ( ( ) => {
2022-09-21 09:00:57 +03:00
setSettings ( initialSettings ) ;
2022-09-21 17:39:46 +03:00
} , [ initialSettings , setSettings ] ) ;
2022-09-15 05:17:30 +03:00
2023-10-18 11:44:26 -07:00
const { data : services } = useSWR ( "/api/services" ) ;
const { data : bookmarks } = useSWR ( "/api/bookmarks" ) ;
const { data : widgets } = useSWR ( "/api/widgets" ) ;
2023-02-21 09:54:05 +02:00
2023-10-17 23:26:55 -07:00
const servicesAndBookmarks = [
... services . map ( ( sg ) => sg . services ) . flat ( ) ,
... bookmarks . map ( ( bg ) => bg . bookmarks ) . flat ( ) ,
] . filter ( ( i ) => i ? . href ) ;
2022-08-24 10:44:35 +03:00
2022-09-15 05:17:30 +03:00
useEffect ( ( ) => {
if ( settings . language ) {
i18n . changeLanguage ( settings . language ) ;
}
2022-09-15 19:58:41 +03:00
if ( settings . theme && theme !== settings . theme ) {
setTheme ( settings . theme ) ;
}
if ( settings . color && color !== settings . color ) {
setColor ( settings . color ) ;
}
} , [ i18n , settings , color , setColor , theme , setTheme ] ) ;
2022-09-15 05:17:30 +03:00
2022-10-18 23:10:44 -07:00
const [ searching , setSearching ] = useState ( false ) ;
2022-10-19 00:26:54 -07:00
const [ searchString , setSearchString ] = useState ( "" ) ;
2023-01-30 23:38:37 -08:00
let searchProvider = null ;
2023-10-17 23:26:55 -07:00
const searchWidget = Object . values ( widgets ) . find ( ( w ) => w . type === "search" ) ;
2023-01-30 23:38:37 -08:00
if ( searchWidget ) {
2023-01-31 00:25:23 -08:00
if ( Array . isArray ( searchWidget . options ? . provider ) ) {
// if search provider is a list, try to retrieve from localstorage, fall back to the first
searchProvider = getStoredProvider ( ) ? ? searchProviders [ searchWidget . options . provider [ 0 ] ] ;
2023-10-17 23:26:55 -07:00
} else if ( searchWidget . options ? . provider === "custom" ) {
2023-01-31 00:58:29 -08:00
searchProvider = {
2023-10-17 23:26:55 -07:00
url : searchWidget . options . url ,
} ;
2023-01-31 00:58:29 -08:00
} else {
searchProvider = searchProviders [ searchWidget . options ? . provider ] ;
2023-01-31 00:33:30 -08:00
}
2023-01-30 23:38:37 -08:00
}
2023-09-03 10:05:25 -04:00
const headerStyle = settings ? . headerStyle || "underlined" ;
2022-10-18 23:10:44 -07:00
useEffect ( ( ) => {
function handleKeyDown ( e ) {
2023-08-29 09:28:23 -07:00
if ( e . target . tagName === "BODY" || e . target . id === "inner_wrapper" ) {
2023-11-13 04:40:09 +01:00
if (
( e . key . length === 1 && e . key . match ( /(\w|\s)/g ) && ! ( e . altKey || e . ctrlKey || e . metaKey || e . shiftKey ) ) ||
( e . key === "v" && ( e . ctrlKey || e . metaKey ) )
) {
2022-10-18 23:10:44 -07:00
setSearching ( true ) ;
} else if ( e . key === "Escape" ) {
setSearchString ( "" ) ;
setSearching ( false ) ;
}
}
}
2023-10-17 23:26:55 -07:00
document . addEventListener ( "keydown" , handleKeyDown ) ;
2022-10-19 00:54:35 -07:00
2022-10-18 23:10:44 -07:00
return function cleanup ( ) {
2023-10-17 23:26:55 -07:00
document . removeEventListener ( "keydown" , handleKeyDown ) ;
} ;
} ) ;
const tabs = useMemo (
( ) => [
... new Set (
Object . keys ( settings . layout ? ? { } )
. map ( ( groupName ) => settings . layout [ groupName ] ? . tab ? . toString ( ) )
. filter ( ( group ) => group ) ,
) ,
] ,
[ settings . layout ] ,
) ;
2023-09-14 22:55:14 +01:00
2023-09-15 08:00:08 -07:00
useEffect ( ( ) => {
if ( ! activeTab ) {
const initialTab = decodeURI ( asPath . substring ( asPath . indexOf ( "#" ) + 1 ) ) ;
2023-10-17 23:26:55 -07:00
setActiveTab ( initialTab === "/" ? slugify ( tabs [ "0" ] ) : initialTab ) ;
2023-09-14 22:55:14 +01:00
}
2023-10-17 23:26:55 -07:00
} ) ;
2023-09-14 22:55:14 +01:00
2023-09-03 07:22:00 -07:00
const servicesAndBookmarksGroups = useMemo ( ( ) => {
2023-10-17 23:26:55 -07:00
const tabGroupFilter = ( g ) => g && [ activeTab , "" ] . includes ( slugify ( settings . layout ? . [ g . name ] ? . tab ) ) ;
const undefinedGroupFilter = ( g ) => settings . layout ? . [ g . name ] === undefined ;
2023-09-14 22:55:14 +01:00
2023-10-17 23:26:55 -07:00
const layoutGroups = Object . keys ( settings . layout ? ? { } )
. map ( ( groupName ) => services ? . find ( ( g ) => g . name === groupName ) ? ? bookmarks ? . find ( ( b ) => b . name === groupName ) )
. filter ( tabGroupFilter ) ;
2023-09-14 22:55:14 +01:00
2023-09-15 15:41:56 +01:00
if ( ! settings . layout && JSON . stringify ( settings . layout ) !== JSON . stringify ( initialSettings . layout ) ) {
// wait for settings to populate (if different from initial settings), otherwise all the widgets will be requested initially even if we are on a single tab
2023-09-14 22:55:14 +01:00
return < div / > ;
}
2023-09-03 07:22:00 -07:00
2023-09-14 22:55:14 +01:00
const serviceGroups = services ? . filter ( tabGroupFilter ) . filter ( undefinedGroupFilter ) ;
const bookmarkGroups = bookmarks . filter ( tabGroupFilter ) . filter ( undefinedGroupFilter ) ;
2023-09-03 07:22:00 -07:00
2023-10-17 23:26:55 -07:00
return (
< >
{ tabs . length > 0 && (
< div key = "tabs" id = "tabs" className = "m-6 sm:m-9 sm:mt-4 sm:mb-0" >
< ul
className = { classNames (
"sm:flex rounded-md bg-theme-100/20 dark:bg-white/5" ,
settings . cardBlur !== undefined &&
` backdrop-blur ${ settings . cardBlur . length ? "-" : "" } ${ settings . cardBlur } ` ,
) }
id = "myTab"
data - tabs - toggle = "#myTabContent"
role = "tablist"
>
{ tabs . map ( ( tab ) => (
< Tab key = { tab } tab = { tab } / >
) ) }
< / ul >
< / div >
) }
{ layoutGroups . length > 0 && (
< div key = "layoutGroups" id = "layout-groups" className = "flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2" >
{ layoutGroups . map ( ( group ) =>
group . services ? (
< ServicesGroup
key = { group . name }
group = { group . name }
services = { group }
layout = { settings . layout ? . [ group . name ] }
fiveColumns = { settings . fiveColumns }
disableCollapse = { settings . disableCollapse }
/ >
) : (
< BookmarksGroup
key = { group . name }
bookmarks = { group }
layout = { settings . layout ? . [ group . name ] }
disableCollapse = { settings . disableCollapse }
/ >
) ,
) }
< / div >
) }
{ serviceGroups ? . length > 0 && (
< div key = "services" id = "services" className = "flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2" >
{ serviceGroups . map ( ( group ) => (
< ServicesGroup
key = { group . name }
group = { group . name }
services = { group }
layout = { settings . layout ? . [ group . name ] }
fiveColumns = { settings . fiveColumns }
disableCollapse = { settings . disableCollapse }
/ >
) ) }
< / div >
) }
{ bookmarkGroups ? . length > 0 && (
< div key = "bookmarks" id = "bookmarks" className = "flex flex-wrap m-4 sm:m-8 sm:mt-4 items-start mb-2" >
{ bookmarkGroups . map ( ( group ) => (
< BookmarksGroup
key = { group . name }
bookmarks = { group }
layout = { settings . layout ? . [ group . name ] }
disableCollapse = { settings . disableCollapse }
/ >
) ) }
< / div >
) }
2023-09-03 07:22:00 -07:00
< / >
2023-10-17 23:26:55 -07:00
) ;
2023-09-03 07:22:00 -07:00
} , [
2023-09-14 22:55:14 +01:00
tabs ,
activeTab ,
2023-09-03 07:22:00 -07:00
services ,
bookmarks ,
settings . layout ,
settings . fiveColumns ,
2023-09-14 22:55:14 +01:00
settings . disableCollapse ,
2023-09-15 15:41:56 +01:00
settings . cardBlur ,
2023-10-17 23:26:55 -07:00
initialSettings . layout ,
2023-09-03 07:22:00 -07:00
] ) ;
2022-08-24 10:44:35 +03:00
return (
2022-09-15 19:58:41 +03:00
< >
< Head >
2023-11-14 22:09:18 -08:00
< title > { initialSettings . title || "Homepage" } < / title >
{ initialSettings . base && < base href = { initialSettings . base } / > }
{ initialSettings . favicon ? (
2022-10-17 15:03:35 +00:00
< >
2023-11-14 22:09:18 -08:00
< link rel = "icon" href = { initialSettings . favicon } / >
< link rel = "apple-touch-icon" sizes = "180x180" href = { initialSettings . favicon } / >
2022-10-17 15:03:35 +00:00
< / >
2022-10-08 16:04:24 +03:00
) : (
2022-10-17 15:03:35 +00:00
< >
2023-10-18 11:44:26 -07:00
< link rel = "apple-touch-icon" sizes = "180x180" href = "/apple-touch-icon.png?v=4" / >
< link rel = "shortcut icon" href = "/homepage.ico" / >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "/favicon-32x32.png?v=4" / >
< link rel = "icon" type = "image/png" sizes = "16x16" href = "/favicon-16x16.png?v=4" / >
2022-10-17 15:03:35 +00:00
< / >
2022-10-08 16:04:24 +03:00
) }
2023-11-14 22:09:18 -08:00
< meta
name = "msapplication-TileColor"
content = { themes [ initialSettings . color || "slate" ] [ initialSettings . theme || "dark" ] }
/ >
< meta name = "theme-color" content = { themes [ initialSettings . color || "slate" ] [ initialSettings . theme || "dark" ] } / >
2022-09-15 19:58:41 +03:00
< / Head >
2023-09-10 23:36:54 +02:00
2023-10-18 11:44:26 -07:00
< link rel = "preload" href = "/api/config/custom.css" as = "fetch" crossOrigin = "anonymous" / >
2023-09-10 23:36:54 +02:00
< style data - name = "custom.css" >
2023-10-17 23:26:55 -07:00
< FileContent
path = "custom.css"
2023-09-10 23:36:54 +02:00
loadingValue = "/* Loading custom CSS... */"
errorValue = "/* Failed to load custom CSS... */"
emptyValue = "/* No custom CSS */"
/ >
< / style >
2023-10-18 11:44:26 -07:00
< link rel = "preload" href = "/api/config/custom.js" as = "fetch" crossOrigin = "anonymous" / >
2023-09-19 14:10:19 -07:00
< script data - name = "custom.js" src = "/api/config/custom.js" async / >
2023-09-10 23:36:54 +02:00
2023-06-09 09:01:19 -07:00
< div className = "relative container m-auto flex flex-col justify-start z-10 h-full" >
2023-08-29 09:28:23 -07:00
< QuickLaunch
servicesAndBookmarks = { servicesAndBookmarks }
searchString = { searchString }
setSearchString = { setSearchString }
isOpen = { searching }
close = { setSearching }
searchProvider = { settings . quicklaunch ? . hideInternetSearch ? null : searchProvider }
/ >
2022-10-08 16:40:36 +03:00
< div
2023-09-10 23:36:54 +02:00
id = "information-widgets"
2022-10-08 16:40:36 +03:00
className = { classNames (
2023-08-21 08:51:35 -07:00
"flex flex-row flex-wrap justify-between" ,
headerStyles [ headerStyle ] ,
2023-10-17 23:26:55 -07:00
settings . cardBlur !== undefined &&
headerStyle === "boxed" &&
` backdrop-blur ${ settings . cardBlur . length ? "-" : "" } ${ settings . cardBlur } ` ,
2022-10-08 16:40:36 +03:00
) }
>
2023-10-17 23:26:55 -07:00
< div
id = "widgets-wrap"
style = { { width : "calc(100% + 1rem)" } }
className = { classNames ( "flex flex-row w-full flex-wrap justify-between -ml-2 -mr-2" ) }
2023-09-16 02:37:24 -07:00
>
{ widgets && (
< >
2022-08-27 00:55:13 +03:00
{ widgets
2023-09-16 02:37:24 -07:00
. filter ( ( widget ) => ! rightAlignedWidgets . includes ( widget . type ) )
2022-09-08 11:47:21 +03:00
. map ( ( widget , i ) => (
2023-10-17 23:26:55 -07:00
< Widget
key = { i }
widget = { widget }
style = { { header : headerStyle , isRightAligned : false , cardBlur : settings . cardBlur } }
/ >
2022-08-27 00:55:13 +03:00
) ) }
2023-09-16 02:37:24 -07:00
2023-10-17 23:26:55 -07:00
< div
id = "information-widgets-right"
className = { classNames (
"m-auto flex flex-wrap grow sm:basis-auto justify-between md:justify-end" ,
headerStyle === "boxedWidgets" ? "sm:ml-4" : "sm:ml-2" ,
) }
>
2023-09-16 02:37:24 -07:00
{ widgets
. filter ( ( widget ) => rightAlignedWidgets . includes ( widget . type ) )
. map ( ( widget , i ) => (
2023-10-17 23:26:55 -07:00
< Widget
key = { i }
widget = { widget }
style = { { header : headerStyle , isRightAligned : true , cardBlur : settings . cardBlur } }
/ >
2023-09-16 02:37:24 -07:00
) ) }
< / div >
< / >
) }
< / div >
2022-09-15 19:58:41 +03:00
< / div >
2022-08-24 10:44:35 +03:00
2023-09-03 07:22:00 -07:00
{ servicesAndBookmarksGroups }
2022-09-15 19:58:41 +03:00
2023-09-10 23:36:54 +02:00
< div id = "footer" className = "flex flex-col mt-auto p-8 w-full" >
< div id = "style" className = "flex w-full justify-end" >
2023-09-03 10:05:25 -04:00
{ ! settings ? . color && < ColorToggle / > }
2023-06-09 09:01:19 -07:00
< Revalidate / >
2023-09-03 10:05:25 -04:00
{ ! settings . theme && < ThemeToggle / > }
2023-06-09 09:01:19 -07:00
< / div >
2022-09-24 01:18:37 +03:00
2023-09-10 23:36:54 +02:00
< div id = "version" className = "flex mt-4 w-full justify-end" >
2023-09-03 10:05:25 -04:00
{ ! settings . hideVersion && < Version / > }
2023-06-09 09:01:19 -07:00
< / div >
2022-09-24 01:18:37 +03:00
< / div >
2022-09-15 19:58:41 +03:00
< / div >
< / >
2022-08-24 10:44:35 +03:00
) ;
}
2022-09-30 22:13:37 +03:00
export default function Wrapper ( { initialSettings , fallback } ) {
2022-09-30 23:34:48 +03:00
const wrappedStyle = { } ;
2023-04-18 22:51:46 -07:00
let backgroundBlur = false ;
let backgroundSaturate = false ;
let backgroundBrightness = false ;
2022-09-30 23:34:48 +03:00
if ( initialSettings && initialSettings . background ) {
2023-04-18 22:51:46 -07:00
let opacity = initialSettings . backgroundOpacity ? ? 1 ;
let backgroundImage = initialSettings . background ;
2023-10-17 23:26:55 -07:00
if ( typeof initialSettings . background === "object" ) {
2023-04-18 22:51:46 -07:00
backgroundImage = initialSettings . background . image ;
backgroundBlur = initialSettings . background . blur !== undefined ;
backgroundSaturate = initialSettings . background . saturate !== undefined ;
backgroundBrightness = initialSettings . background . brightness !== undefined ;
if ( initialSettings . background . opacity !== undefined ) opacity = initialSettings . background . opacity / 100 ;
}
2022-09-30 23:34:48 +03:00
const opacityValue = 1 - opacity ;
wrappedStyle . backgroundImage = `
linear - gradient (
rgb ( var ( -- bg - color ) / $ { opacityValue } ) ,
rgb ( var ( -- bg - color ) / $ { opacityValue } )
) ,
2023-04-18 22:51:46 -07:00
url ( $ { backgroundImage } ) ` ;
2022-09-30 23:34:48 +03:00
wrappedStyle . backgroundPosition = "center" ;
wrappedStyle . backgroundSize = "cover" ;
}
2022-09-30 22:13:37 +03:00
return (
< div
id = "page_wrapper"
className = { classNames (
2022-09-30 23:34:48 +03:00
"relative" ,
2022-09-30 22:13:37 +03:00
initialSettings . theme && initialSettings . theme ,
2023-10-17 23:26:55 -07:00
initialSettings . color && ` theme- ${ initialSettings . color } ` ,
2022-09-30 22:13:37 +03:00
) }
>
< div
id = "page_container"
className = "fixed overflow-auto w-full h-full bg-theme-50 dark:bg-theme-800 transition-all"
2022-09-30 23:34:48 +03:00
style = { wrappedStyle }
2022-09-30 22:13:37 +03:00
>
2023-04-18 22:51:46 -07:00
< div
2023-10-17 23:26:55 -07:00
id = "inner_wrapper"
tabIndex = "-1"
className = { classNames (
"fixed overflow-auto w-full h-full" ,
backgroundBlur &&
` backdrop-blur ${ initialSettings . background . blur . length ? "-" : "" } ${ initialSettings . background . blur } ` ,
backgroundSaturate && ` backdrop-saturate- ${ initialSettings . background . saturate } ` ,
backgroundBrightness && ` backdrop-brightness- ${ initialSettings . background . brightness } ` ,
) }
>
2023-04-18 22:51:46 -07:00
< Index initialSettings = { initialSettings } fallback = { fallback } / >
< / div >
2022-09-30 22:13:37 +03:00
< / div >
< / div >
) ;
}