mobile: update theme selector

This commit is contained in:
ammarahm-ed
2023-07-18 12:48:42 +05:00
parent 403b2809b7
commit eedf347708
19 changed files with 892 additions and 285 deletions

View File

@@ -98,7 +98,10 @@ export const UserStatus = () => {
<>
Synced{" "}
<TimeSince
style={{ fontSize: SIZE.xs, color: colors.secondary.paragraph }}
style={{
fontSize: SIZE.xs,
color: colors.secondary.paragraph
}}
time={lastSynced}
bold={true}
/>
@@ -114,7 +117,7 @@ export const UserStatus = () => {
!user || lastSyncStatus === SyncStatus.Failed
? colors.error.icon
: isOffline
? colors.warning.icon
? colors.static.orange
: colors.success.icon
}
/>
@@ -142,7 +145,11 @@ export const UserStatus = () => {
syncing ? (
<ActivityIndicator color={colors.primary.accent} size={SIZE.xl} />
) : lastSyncStatus === SyncStatus.Failed ? (
<Icon color={colors.error.icon} name="sync-alert" size={SIZE.lg} />
<Icon
color={colors.error.icon}
name="sync-alert"
size={SIZE.lg}
/>
) : (
<Icon color={colors.primary.accent} name="sync" size={SIZE.lg} />
)

View File

@@ -133,9 +133,9 @@ export const useButton = ({
selected: colors.error.background
},
warn: {
primary: colors.warning.background,
text: colors.warning.paragraph,
selected: colors.warning.background
primary: colors.static.orange,
text: colors.static.white,
selected: colors.static.orange
}
};

View File

@@ -88,14 +88,14 @@ export default function DebugLogs() {
item.level === LogLevel.Error || item.level === LogLevel.Fatal
? hexToRGBA(colors.error.paragraph, 0.2)
: item.level === LogLevel.Warn
? hexToRGBA(colors.warning.icon, 0.2)
? hexToRGBA(colors.static.orange, 0.2)
: "transparent";
const color =
item.level === LogLevel.Error || item.level === LogLevel.Fatal
? colors.error.paragraph
: item.level === LogLevel.Warn
? colors.warning.icon
? colors.static.black
: colors.primary.paragraph;
return !item ? null : (
@@ -134,7 +134,6 @@ export default function DebugLogs() {
},
[
colors.secondary.background,
colors.warning.icon,
colors.primary.paragraph,
colors.error.paragraph
]

View File

@@ -16,23 +16,37 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { ThemeDefinition, useThemeColors } from "@notesnook/theme";
import type { ThemesRouter } from "@notesnook/themes-server";
import { THEME_COMPATIBILITY_VERSION, useThemeColors } from "@notesnook/theme";
import type {
CompiledThemeDefinition,
ThemeMetadata,
ThemesRouter
} from "@notesnook/themes-server";
import Icon from "react-native-vector-icons/MaterialCommunityIcons";
import { MasonryFlashList } from "@shopify/flash-list";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createTRPCProxyClient, httpBatchLink } from "@trpc/client";
import { createTRPCReact } from "@trpc/react-query";
import React, { useState } from "react";
import { ActivityIndicator, TouchableOpacity, View } from "react-native";
import {
ActivityIndicator,
Linking,
TouchableOpacity,
View
} from "react-native";
import { db } from "../../common/database";
import SheetProvider from "../../components/sheet-provider";
import { Button } from "../../components/ui/button";
import Input from "../../components/ui/input";
import Heading from "../../components/ui/typography/heading";
import Paragraph from "../../components/ui/typography/paragraph";
import { ToastEvent, presentSheet } from "../../services/event-manager";
import { useThemeStore } from "../../stores/use-theme-store";
import { SIZE } from "../../utils/size";
import { MasonryFlashList } from "@shopify/flash-list";
import Input from "../../components/ui/input";
const THEME_SERVER_URL = "http://192.168.43.127:1000";
import { getElevationStyle } from "../../utils/elevation";
import { MenuItemsList } from "../../utils/constants";
const THEME_SERVER_URL = "http://192.168.43.127:9000";
//@ts-ignore
export const themeTrpcClient = createTRPCProxyClient<ThemesRouter>({
links: [
@@ -44,35 +58,44 @@ export const themeTrpcClient = createTRPCProxyClient<ThemesRouter>({
function ThemeSelector() {
const { colors } = useThemeColors();
const themeColors = colors;
const [searchQuery, setSearchQuery] = useState<string>();
const [colorScheme, setColorScheme] = useState<string>();
const themes = trpc.themes.useInfiniteQuery(
{
limit: 10
limit: 10,
compatibilityVersion: THEME_COMPATIBILITY_VERSION,
filters: [
...(searchQuery && searchQuery !== ""
? [
{
type: "term" as const,
value: searchQuery
}
]
: []),
...(colorScheme && colorScheme !== ""
? [
{
type: "colorScheme" as const,
value: colorScheme
}
]
: [])
]
},
{
getNextPageParam: (lastPage) => lastPage.nextCursor
}
);
const [searchQuery, setSearchQuery] = useState<string>();
const searchResults = trpc.search.useInfiniteQuery(
{ limit: 10, query: searchQuery || "" },
{
enabled: false,
getNextPageParam: (lastPage) => lastPage.nextCursor
}
);
const select = (item: Partial<ThemeDefinition>) => {
const select = (item: Partial<ThemeMetadata>) => {
presentSheet({
context: item.id,
component: (ref, close) => <ThemeSetter close={close} theme={item} />
});
};
const renderItem = ({
item
}: {
item: Omit<ThemeDefinition, "scopes" | "codeBlockCss">;
index: number;
}) => {
const renderItem = ({ item }: { item: ThemeMetadata; index: number }) => {
const colors = item.previewColors;
return (
@@ -81,77 +104,150 @@ function ThemeSelector() {
<TouchableOpacity
activeOpacity={0.9}
style={{
backgroundColor: colors?.background,
borderRadius: 10,
padding: 12,
padding: 6,
marginBottom: 10,
flexShrink: 1,
borderWidth: 1,
borderColor: colors?.accent,
marginHorizontal: 5
flexShrink: 1
}}
onPress={() => select(item)}
>
<View
style={{
backgroundColor: colors?.accent,
height: 40,
backgroundColor: colors?.background,
height: 200,
width: "100%",
borderRadius: 10
}}
/>
<View
style={{
borderRadius: 10,
marginBottom: 10,
overflow: "hidden",
flexDirection: "row",
marginTop: 6
justifyContent: "space-between",
...getElevationStyle(3)
}}
>
<View
style={{
flex: 1,
backgroundColor: colors?.shade,
height: 40,
borderRadius: 10,
marginRight: 6
height: "100%",
width: "49.5%",
backgroundColor: colors.navigationMenu.background,
padding: 5,
paddingVertical: 3,
borderRadius: 5
}}
/>
>
{MenuItemsList.map((item, index) => (
<View
key={item.name}
style={{
height: 12,
width: "100%",
backgroundColor:
index === 0
? colors.navigationMenu.accent + 40
: colors.navigationMenu.background,
borderRadius: 2,
paddingHorizontal: 3,
flexDirection: "row",
alignItems: "center",
marginBottom: 4
}}
>
<Icon
size={8}
name={item.icon}
color={
index === 0
? colors.navigationMenu.accent
: colors.navigationMenu.icon
}
/>
<View
style={{
height: 3,
width: "40%",
backgroundColor:
index === 0
? colors.navigationMenu.accent
: colors.paragraph,
borderRadius: 2,
marginLeft: 3
}}
></View>
</View>
))}
</View>
<View
style={{
flex: 1,
backgroundColor: colors?.secondaryBackground,
height: 40,
borderRadius: 10
height: "100%",
width: "49.5%",
backgroundColor: colors.list.background,
borderRadius: 5,
paddingHorizontal: 2,
paddingRight: 6
}}
/>
>
<View
style={{
height: 12,
width: "100%",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginTop: 3
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center"
}}
>
<Icon size={8} color={colors.list.heading} name="menu" />
<Heading
style={{
marginLeft: 3
}}
color={colors.list.heading}
size={7}
>
Notes
</Heading>
</View>
<Icon name="magnify" color={colors.list.heading} size={7} />
</View>
</View>
</View>
<Heading size={SIZE.md} color={colors?.heading}>
<Heading size={SIZE.md} color={themeColors.primary.heading}>
{item.name}
</Heading>
<Paragraph color={colors?.paragraph}>{item.description}</Paragraph>
<Paragraph size={SIZE.xs} color={colors?.paragraph}>
By {item.author}
{/* <Paragraph color={themeColors.primary?.paragraph}>
{item.description}
</Paragraph> */}
<Paragraph size={SIZE.xs} color={themeColors.secondary?.paragraph}>
By {item.authors?.[0].name}
</Paragraph>
</TouchableOpacity>
</>
);
};
let resetTimer: NodeJS.Timeout;
let refetchTimer: NodeJS.Timeout;
//let refetchTimer: NodeJS.Timeout;
const onSearch = (text: string) => {
clearTimeout(resetTimer as NodeJS.Timeout);
resetTimer = setTimeout(() => {
setSearchQuery(text);
clearTimeout(refetchTimer);
refetchTimer = setTimeout(() => {
searchResults.refetch();
}, 300);
}, 500);
// clearTimeout(refetchTimer);
// refetchTimer = setTimeout(() => {
// themes.refetch();
// }, 300);
}, 400);
};
function getThemes() {
const pages = searchQuery ? searchResults.data?.pages : themes.data?.pages;
function getThemes(): ThemeMetadata[] {
const pages = themes.data?.pages;
return (
pages
?.map((page) => {
@@ -170,10 +266,46 @@ function ThemeSelector() {
>
<View
style={{
paddingHorizontal: 4
paddingHorizontal: 4,
marginBottom: 12
}}
>
<Input onChangeText={onSearch} placeholder="Search themes" />
<View
style={{
flexDirection: "row",
columnGap: 10
}}
>
<Button
height={35}
style={{ borderRadius: 100 }}
type={colorScheme === "" || !colorScheme ? "accent" : "grayBg"}
title="All"
onPress={() => {
setColorScheme("");
}}
/>
<Button
style={{ borderRadius: 100 }}
height={35}
type={colorScheme === "dark" ? "accent" : "grayBg"}
title="Dark"
onPress={() => {
setColorScheme("dark");
}}
/>
<Button
style={{ borderRadius: 100 }}
height={35}
type={colorScheme === "light" ? "accent" : "grayBg"}
title="Light"
onPress={() => {
setColorScheme("light");
}}
/>
</View>
</View>
<MasonryFlashList
@@ -188,7 +320,7 @@ function ThemeSelector() {
alignItems: "center"
}}
>
{themes.isLoading || searchResults.isLoading ? (
{themes.isLoading ? (
<ActivityIndicator color={colors.primary.accent} />
) : searchQuery ? (
<Paragraph color={colors.secondary.paragraph}>
@@ -203,12 +335,7 @@ function ThemeSelector() {
renderItem={renderItem}
onEndReachedThreshold={0.1}
onEndReached={() => {
if (searchQuery) {
console.log("fetching next page");
searchResults.fetchNextPage();
} else {
themes.fetchNextPage();
}
themes.fetchNextPage();
}}
/>
</View>
@@ -242,9 +369,11 @@ const ThemeSetter = ({
theme,
close
}: {
theme: Partial<ThemeDefinition>;
theme: Partial<CompiledThemeDefinition>;
close?: (ctx?: string) => void;
}) => {
const themeColors = useThemeColors();
const colors = theme?.previewColors;
return (
@@ -256,7 +385,6 @@ const ThemeSetter = ({
>
<View
style={{
backgroundColor: colors?.background,
borderRadius: 10,
marginBottom: 12,
padding: 12
@@ -264,47 +392,181 @@ const ThemeSetter = ({
>
<View
style={{
backgroundColor: colors?.accent,
height: 70,
width: "100%",
borderRadius: 10
}}
/>
<View
style={{
flexDirection: "row",
marginTop: 6,
marginBottom: 10
justifyContent: "center",
alignItems: "center",
backgroundColor: colors?.accent + "20",
padding: 12,
borderRadius: 15,
marginBottom: 12
}}
>
<View
style={{
flex: 1,
backgroundColor: colors?.shade,
height: 50,
backgroundColor: colors?.background,
borderWidth: 0.5,
borderColor: colors?.border,
height: 200,
width: "100%",
borderRadius: 10,
marginRight: 6
marginBottom: 10,
overflow: "hidden",
flexDirection: "row",
justifyContent: "space-between",
...getElevationStyle(3),
maxWidth: 200
}}
/>
>
<View
style={{
height: "100%",
width: "49.5%",
backgroundColor: colors?.navigationMenu.background,
padding: 5,
paddingVertical: 3,
borderRadius: 5
}}
>
{MenuItemsList.map((item, index) => (
<View
key={item.name}
style={{
height: 12,
width: "100%",
backgroundColor:
index === 0
? //@ts-ignore
colors?.navigationMenu?.accent + 40
: colors?.navigationMenu.background,
borderRadius: 2,
paddingHorizontal: 3,
flexDirection: "row",
alignItems: "center",
marginBottom: 4
}}
>
<Icon
size={8}
name={item.icon}
color={
index === 0
? colors?.navigationMenu.accent
: colors?.navigationMenu.icon
}
/>
<View
style={{
flex: 1,
backgroundColor: colors?.secondaryBackground,
height: 50,
borderRadius: 10
}}
/>
<View
style={{
height: 3,
width: "40%",
backgroundColor:
index === 0
? colors?.navigationMenu.accent
: colors?.paragraph,
borderRadius: 2,
marginLeft: 3
}}
></View>
</View>
))}
</View>
<View
style={{
height: "100%",
width: "49.5%",
backgroundColor: colors?.list.background,
borderRadius: 5,
paddingHorizontal: 2,
paddingRight: 6
}}
>
<View
style={{
height: 12,
width: "100%",
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
marginTop: 3
}}
>
<View
style={{
flexDirection: "row",
alignItems: "center"
}}
>
<Icon size={8} color={colors?.list.heading} name="menu" />
<Heading
style={{
marginLeft: 3
}}
color={colors?.list.heading}
size={7}
>
Notes
</Heading>
</View>
<Icon name="magnify" color={colors?.list.heading} size={7} />
</View>
</View>
</View>
</View>
<Heading size={SIZE.md} color={colors?.heading}>
<Heading size={SIZE.md} color={themeColors.colors.primary.heading}>
{theme.name}
</Heading>
<Paragraph color={colors?.paragraph}>{theme.description}</Paragraph>
<Paragraph size={SIZE.xs} color={colors?.paragraph}>
By {theme.author}
<Paragraph color={themeColors.colors.primary.paragraph}>
{theme.description}
</Paragraph>
<Paragraph
size={SIZE.xs}
color={themeColors.colors.secondary.paragraph}
>
By {theme.authors?.[0]?.name}
</Paragraph>
<View
style={{
marginTop: 5,
flexDirection: "column",
rowGap: 3
}}
>
<Paragraph
size={SIZE.xs}
color={themeColors.colors.secondary.paragraph}
>
Version {theme.version}
</Paragraph>
<Paragraph
size={SIZE.xs}
color={themeColors.colors.secondary.paragraph}
>
{theme.license}
</Paragraph>
{theme.homepage ? (
<View
style={{
flexDirection: "row"
}}
>
<Paragraph
size={SIZE.xs}
color={themeColors.colors.secondary.accent}
onPress={() => {
Linking.openURL(theme.homepage as string);
}}
>
Visit homepage
</Paragraph>
</View>
) : null}
</View>
</View>
<Button
@@ -315,7 +577,12 @@ const ThemeSetter = ({
onPress={async () => {
if (!theme.id) return;
try {
const fullTheme = await themeTrpcClient.getTheme.query(theme.id);
const user = await db.user?.getUser();
const fullTheme = await themeTrpcClient.installTheme.query({
compatibilityVersion: THEME_COMPATIBILITY_VERSION,
id: theme.id,
userId: user?.id
});
if (!fullTheme) return;
theme.colorScheme === "dark"
? useThemeStore.getState().setDarkTheme(fullTheme)
@@ -338,7 +605,7 @@ const ThemeSetter = ({
? "Set as dark theme"
: "Set as light theme"
}
type="grayBg"
type="grayAccent"
/>
</View>
</>

File diff suppressed because it is too large Load Diff

View File

@@ -24,17 +24,17 @@
},
"devDependencies": {
"otplib": "12.0.1",
"react-refresh": "0.14.0",
"patch-package": "7.0.0"
"patch-package": "7.0.0",
"react-refresh": "0.14.0"
},
"dependencies": {
"react": "18.2.0",
"react-native": "0.72.0",
"@notesnook/common": "file:../../packages/common",
"@notesnook/core": "file:../../packages/core",
"@notesnook/editor": "file:../../packages/editor",
"@notesnook/editor-mobile": "file:../../packages/editor-mobile",
"@notesnook/logger": "file:../../packages/logger",
"@notesnook/common": "file:../../packages/common",
"@notesnook/themes-server": "file:../../servers/themes"
"@notesnook/themes-server": "file:../../servers/themes",
"react": "18.2.0",
"react-native": "0.72.0"
}
}

View File

@@ -417,6 +417,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -463,11 +464,15 @@
"@orama/orama": "^1.0.8",
"@trpc/server": "10.31.0",
"async-mutex": "^0.4.0",
"cors": "^2.8.5",
"util": "^0.12.5",
"zod": "^3.21.4"
},
"devDependencies": {
"@notesnook/theme": "file:../../packages/theme",
"@types/cors": "^2.8.13",
"@vitejs/plugin-react": "^4.0.3",
"react": "17.0.2",
"vite-node": "^0.33.0"
}
},

View File

@@ -111,6 +111,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -23785,6 +23786,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"tinycolor2": "^1.4.2",
"ts-json-schema-generator": "^1.2.0"
}

View File

@@ -128,6 +128,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -21646,6 +21647,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"tinycolor2": "^1.4.2",
"ts-json-schema-generator": "^1.2.0"
}

View File

@@ -143,6 +143,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -4353,6 +4354,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"tinycolor2": "^1.4.2",
"ts-json-schema-generator": "^1.2.0"
}

View File

@@ -19,6 +19,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -699,6 +700,16 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/isomorphic-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
"integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
"dev": true,
"dependencies": {
"node-fetch": "^2.6.1",
"whatwg-fetch": "^3.4.1"
}
},
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -726,6 +737,26 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node_modules/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"dev": true,
"dependencies": {
"whatwg-url": "^5.0.0"
},
"engines": {
"node": "4.x || >=6.0.0"
},
"peerDependencies": {
"encoding": "^0.1.0"
},
"peerDependenciesMeta": {
"encoding": {
"optional": true
}
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -918,6 +949,12 @@
"node": ">=4"
}
},
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
"node_modules/ts-json-schema-generator": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-1.2.0.tgz",
@@ -992,6 +1029,28 @@
"node": ">=4.2.0"
}
},
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true
},
"node_modules/whatwg-fetch": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
"dev": true
},
"node_modules/whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"dependencies": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
@@ -1572,6 +1631,16 @@
"has": "^1.0.3"
}
},
"isomorphic-fetch": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz",
"integrity": "sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==",
"dev": true,
"requires": {
"node-fetch": "^2.6.1",
"whatwg-fetch": "^3.4.1"
}
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -1593,6 +1662,15 @@
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
},
"node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"dev": true,
"requires": {
"whatwg-url": "^5.0.0"
}
},
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -1734,6 +1812,12 @@
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog=="
},
"tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"dev": true
},
"ts-json-schema-generator": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ts-json-schema-generator/-/ts-json-schema-generator-1.2.0.tgz",
@@ -1788,6 +1872,28 @@
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true
},
"webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
"dev": true
},
"whatwg-fetch": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz",
"integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==",
"dev": true
},
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
"dev": true,
"requires": {
"tr46": "~0.0.3",
"webidl-conversions": "^3.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",

View File

@@ -18,6 +18,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {

View File

@@ -16,7 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import "isomorphic-fetch";
import { mkdir, writeFile } from "fs/promises";
import path from "path";
import { fileURLToPath } from "url";

View File

@@ -29,9 +29,11 @@ import {
import { colorsToCss } from "../theme/transformer";
import _ThemeLight from "./themes/default-light.json";
import _ThemeDark from "./themes/default-dark.json";
import _ThemePitchBlack from "./themes/default-pitch-black.json";
const ThemeLight = _ThemeLight as ThemeDefinition;
const ThemeDark = _ThemeDark as ThemeDefinition;
const ThemePitchBlack = _ThemePitchBlack as ThemeDefinition;
type ThemeScope = {
colors: VariantsWithStaticColors<true>;
@@ -115,7 +117,7 @@ export const useCurrentThemeScope = () => useContext(ThemeScopeContext);
export const ThemeProvider = ThemeContext.Provider;
export const ScopedThemeProvider = ThemeScopeContext.Provider;
export const THEME_COMPATIBILITY_VERSION: ThemeCompatibilityVersion = 1;
export { ThemeLight, ThemeDark };
export { ThemeLight, ThemeDark, ThemePitchBlack };
function buildVariants(
scope: keyof ThemeScopes,

View File

@@ -51,6 +51,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {

View File

@@ -12,11 +12,13 @@
"@orama/orama": "^1.0.8",
"@trpc/server": "10.31.0",
"async-mutex": "^0.4.0",
"cors": "^2.8.5",
"util": "^0.12.5",
"zod": "^3.21.4"
},
"devDependencies": {
"@notesnook/theme": "file:../../packages/theme",
"@types/cors": "^2.8.13",
"@vitejs/plugin-react": "^4.0.3",
"react": "17.0.2",
"vite-node": "^0.33.0"
@@ -38,6 +40,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"ts-json-schema-generator": "^1.2.0"
},
"peerDependencies": {
@@ -812,6 +815,21 @@
"https://trpc.io/sponsor"
]
},
"node_modules/@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"dev": true,
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/node": {
"version": "20.4.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz",
"integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==",
"dev": true
},
"node_modules/@vitejs/plugin-react": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.3.tgz",
@@ -981,6 +999,18 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"node_modules/cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"dependencies": {
"object-assign": "^4",
"vary": "^1"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -1351,7 +1381,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -1537,6 +1566,14 @@
"which-typed-array": "^1.1.2"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
"engines": {
"node": ">= 0.8"
}
},
"node_modules/vite": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz",
@@ -2109,6 +2146,7 @@
"@trpc/server": "^10.31.0",
"@types/react": "17.0.2",
"@types/tinycolor2": "^1.4.3",
"isomorphic-fetch": "^3.0.0",
"tinycolor2": "^1.4.2",
"ts-json-schema-generator": "^1.2.0"
}
@@ -2123,6 +2161,21 @@
"resolved": "https://registry.npmjs.org/@trpc/server/-/server-10.31.0.tgz",
"integrity": "sha512-9EnRTSDE9nF11LZsvSOqNKqkRYzHqFX4ch5AJ6VIu8uta2vxVTN4FxxsNRSOluTzVYZDeaCISbwmOJ5iihCCIg=="
},
"@types/cors": {
"version": "2.8.13",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz",
"integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/node": {
"version": "20.4.2",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz",
"integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==",
"dev": true
},
"@vitejs/plugin-react": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.0.3.tgz",
@@ -2228,6 +2281,15 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"cors": {
"version": "2.8.5",
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
"requires": {
"object-assign": "^4",
"vary": "^1"
}
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -2482,8 +2544,7 @@
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="
},
"pathe": {
"version": "1.1.1",
@@ -2604,6 +2665,11 @@
"which-typed-array": "^1.1.2"
}
},
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
},
"vite": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-4.4.3.tgz",

View File

@@ -13,11 +13,13 @@
"@orama/orama": "^1.0.8",
"@trpc/server": "10.31.0",
"async-mutex": "^0.4.0",
"cors": "^2.8.5",
"util": "^0.12.5",
"zod": "^3.21.4"
},
"devDependencies": {
"@notesnook/theme": "file:../../packages/theme",
"@types/cors": "^2.8.13",
"@vitejs/plugin-react": "^4.0.3",
"react": "17.0.2",
"vite-node": "^0.33.0"

View File

@@ -20,3 +20,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { ThemesAPI } from "./api";
export type ThemesRouter = typeof ThemesAPI;
export type { CompiledThemeDefinition, ThemeMetadata } from "./sync";

View File

@@ -20,8 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
import { createHTTPServer } from "@trpc/server/adapters/standalone";
import { ThemesAPI } from "./api";
import { syncThemes } from "./sync";
import cors from "cors";
const server = createHTTPServer({
middleware: cors(),
router: ThemesAPI
});
const PORT = parseInt(process.env.PORT || "9000");