diff --git a/.gitignore b/.gitignore index 8a44f4b7..1e911201 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +# icons +icons/* +!icons/create_icon.sh +!icons/1024x1024.png + .idea # prisma diff --git a/apps/electron/electron.vite.config.ts b/apps/electron/electron.vite.config.ts index 1c26b69d..0f9fc735 100644 --- a/apps/electron/electron.vite.config.ts +++ b/apps/electron/electron.vite.config.ts @@ -1,9 +1,15 @@ import { resolve } from "path"; import { defineConfig, externalizeDepsPlugin } from "electron-vite"; +import { sentryVitePlugin } from "@sentry/vite-plugin"; import react from "@vitejs/plugin-react"; +const IS_DEV = process.env.NODE_ENV === "development"; + export default defineConfig({ main: { + build: { + sourcemap: true, + }, plugins: [ externalizeDepsPlugin({ exclude: [ @@ -20,6 +26,16 @@ export default defineConfig({ "sharp", ], }), + + !IS_DEV && + sentryVitePlugin({ + org: "meetqy", + project: "rao-pics", + // Auth tokens can be obtained from https://sentry.io/settings/account/api/auth-tokens/ + // and need `project:releases` and `org:read` scopes + authToken: + "7979f62cdaee7ba46204863b5777bec04eed627ccb7a2c5d32262ad3a04672e7", + }), ], }, preload: { diff --git a/apps/electron/package.json b/apps/electron/package.json index 7ff73a67..6281ffa7 100644 --- a/apps/electron/package.json +++ b/apps/electron/package.json @@ -14,9 +14,10 @@ "build:mac": "pnpm clean:dist && pnpm build && electron-builder --mac --config ./electron-builder.cjs", "build:win": "pnpm clean:dist && pnpm build && electron-builder --win --config", "clean": "git clean -xdf .turbo node_modules out dist", - "clean:dist": "git clean -xdf dist", + "clean:dist": "git clean -xdf dist/*", "dev": "electron-vite dev", "format": "prettier --check \"**/*.{mjs,ts,md,json}\"", + "postinstall": "electron-builder install-app-deps", "lint": "eslint .", "start": "electron-vite preview", "typecheck": "pnpm typecheck:node && pnpm typecheck:web", @@ -50,6 +51,8 @@ "@rao-pics/prettier-config": "workspace:^", "@rao-pics/tailwind-config": "workspace:*", "@rao-pics/tsconfig": "^0.1.0", + "@sentry/electron": "^4.11.0", + "@sentry/vite-plugin": "^2.7.1", "@types/ip": "^1.1.0", "@types/lodash": "^4.14.197", "@types/node": "^18.17.6", diff --git a/apps/electron/src/main/index.ts b/apps/electron/src/main/index.ts index e852b245..30963be9 100644 --- a/apps/electron/src/main/index.ts +++ b/apps/electron/src/main/index.ts @@ -3,6 +3,7 @@ import { join } from "path"; import { app, BrowserWindow, dialog, shell } from "electron"; import { createIPCHandler } from "electron-trpc/main"; import { electronApp, optimizer } from "@electron-toolkit/utils"; +import * as Sentry from "@sentry/electron"; import getPort, { portNumbers } from "get-port"; import ip from "ip"; @@ -14,13 +15,20 @@ import { createDbPath } from "@rao-pics/db"; import icon from "../../resources/icon.png?asset"; import { createCustomIPCHandle } from "./src/ipc"; -const caller = router.createCaller({}); +/** + * Sentry init + */ +Sentry.init({ + dsn: "https://178a415c4ef2421a8f52b6c4041319af@o4505321607397376.ingest.sentry.io/4505321612705792", + debug: IS_DEV, +}); const controller = new AbortController(); const { signal } = controller; // 获取端口 async function initConfig() { + const caller = router.createCaller({}); const config = await caller.config.get(); const serverPort = @@ -31,9 +39,39 @@ async function initConfig() { return await caller.config.upsert({ serverPort, clientPort, + ip: ip.address(), }); } +const mainWindowReadyToShow = async () => { + const config = await initConfig(); + await startExpressServer(); + + const { clientPort } = config; + + if (!clientPort) return; + + if (!IS_DEV) { + const child = cp.fork( + join( + process.resourcesPath, + "themes", + config?.theme ?? DEFAULT_THEME, + "server.js", + ), + ["child"], + { + env: { PORT: clientPort.toString(), HOSTNAME: "0.0.0.0" }, + signal, + }, + ); + + child.on("error", (e) => { + console.error(e); + }); + } +}; + function createWindow(): void { // Create the browser window. const mainWindow = new BrowserWindow({ @@ -58,9 +96,6 @@ function createWindow(): void { mainWindow.on("ready-to-show", () => { mainWindow.show(); - void caller.config.upsert({ - ip: ip.address(), - }); }); mainWindow.webContents.setWindowOpenHandler((details) => { @@ -78,8 +113,8 @@ function createWindow(): void { void mainWindow.loadFile(join(__dirname, "../renderer/index.html")); } + void mainWindowReadyToShow(); createIPCHandler({ router, windows: [mainWindow] }); - createCustomIPCHandle(); } @@ -88,40 +123,10 @@ function createWindow(): void { // Some APIs can only be used after this event occurs. app .whenReady() - .then(async () => { + .then(() => { // Set app user model id for windows electronApp.setAppUserModelId("com.rao-pics"); - const config = await initConfig(); - await startExpressServer(); - // 启动静态资源服务器 - // await startStaticServer(); - - const { clientPort } = config; - - if (!clientPort) return; - - if (!IS_DEV) { - const child = cp.fork( - join( - process.resourcesPath, - "themes", - config?.theme ?? DEFAULT_THEME, - "server.js", - ), - ["child"], - { - env: { PORT: clientPort.toString(), HOSTNAME: "0.0.0.0" }, - signal, - }, - ); - - child.on("error", (e) => { - dialog.showErrorBox("child process fork error", e.message); - controller.abort(); - }); - } - // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. // see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils diff --git a/icons/1024x1024.png b/icons/1024x1024.png new file mode 100644 index 00000000..0fd51111 Binary files /dev/null and b/icons/1024x1024.png differ diff --git a/icons/create_icon.sh b/icons/create_icon.sh new file mode 100755 index 00000000..f01aa4cd --- /dev/null +++ b/icons/create_icon.sh @@ -0,0 +1,132 @@ +#!/bin/bash + +set -eo pipefail + +# Config +SOURCE_FILE_PATH='./1024x1024.png' # has to be of size 1024x1024 px +OUT_ICON_NAME='icon' + + +# The "design" and magic numbers below are derived from Apple's macOS app icon +# guidelines and design templates: +# https://developer.apple.com/design/human-interface-guidelines/macos/icons-and-images/app-icon/ +# https://developer.apple.com/design/resources/#macos-apps +# +# Specifically, for an icon of 1024x: +# - outer bounding box: 1024x1024 px +# - border radius: ~22,85% (= 234 px) +# - icon grid size: 824x824 px +# - icon grid shadow size: x: 0px, y: 10px, blur: 10px, 30% black + + +# Make sure ImageMagick's convert and iconutil are available. +if ! hash convert 2>/dev/null || ! hash iconutil 2>/dev/null; then + echo "ERROR: This script requires ImageMagick and iconutil." + exit 1 +fi + + +# Prepare an iconset folder +mkdir "./${OUT_ICON_NAME}.iconset" +mkdir "./${OUT_ICON_NAME}_shadow_rounded.iconset" +mkdir "./${OUT_ICON_NAME}_rounded.iconset" + + +# Add rounded corners to the 1024px image. +# +# This works by: +# 1. Generating a black square (1024 px) with rounded corners (radius 234 px) +# on transparent background, via `-size [...] xc:none -draw [...]` +# 2. Applying the square as a mask to the the source image, via `-matte [...]` +convert "${SOURCE_FILE_PATH}" \ + -matte \( \ + -size 1024x1024 xc:none -draw "roundrectangle 0,0,1024,1024,234,234" \ + \) \ + -compose DstIn -composite \ + "./${OUT_ICON_NAME}.iconset/temp_1024_rounded.png" + + +convert "${SOURCE_FILE_PATH}" \ + -resize 824x824 \ + "./${OUT_ICON_NAME}.iconset/temp_1024.png" + + +# Apply sizing and add shadow to the 1024px image. +# +# This works by: +# 1. Resizing to 'icon grid size' (824px), via `-resize` +# 2. Adding padding (100px) to get 'outer bounding box' size, +# via `-bordercolor none -border [...]` +# 3. Adding shadow, via `+clone -background black -shadow [...]` +convert "./${OUT_ICON_NAME}.iconset/temp_1024_rounded.png" \ + -resize 824x824 \ + -bordercolor none -border 100x100 \ + \( +clone -background black -shadow 30x10+0+10 -background none \) \ + -compose DstOver -flatten \ + "./${OUT_ICON_NAME}_shadow_rounded.iconset/icon_512x512@2x.png" + +convert "./${OUT_ICON_NAME}.iconset/temp_1024_rounded.png" \ + -resize 824x824 \ + -bordercolor none -border 0x0 \ + \( +clone -background none \) \ + -compose DstOver -flatten \ + "./${OUT_ICON_NAME}_rounded.iconset/icon_512x512@2x.png" + +convert "./${OUT_ICON_NAME}.iconset/temp_1024.png" \ + -resize 824x824 \ + "./${OUT_ICON_NAME}.iconset/icon_512x512@2x.png" + +# Remove temporary file +rm "./${OUT_ICON_NAME}.iconset/temp_1024_rounded.png" +rm "./${OUT_ICON_NAME}.iconset/temp_1024.png" + +# Generate all sizes. +# 16/32/128/256/512, each single & double resolution +cd "./${OUT_ICON_NAME}.iconset/" +convert './icon_512x512@2x.png' \ + \( +clone -resize x16 -write './icon_16x16.png' +delete \) \ + \( +clone -resize x32 -write './icon_16x16@2x.png' +delete \) \ + \( +clone -resize x32 -write './icon_32x32.png' +delete \) \ + \( +clone -resize x64 -write './icon_32x32@2x.png' +delete \) \ + \( +clone -resize x128 -write './icon_128x128.png' +delete \) \ + \( +clone -resize x256 -write './icon_128x128@2x.png' +delete \) \ + \( +clone -resize x256 -write './icon_256x256.png' +delete \) \ + \( +clone -resize x512 -write './icon_256x256@2x.png' +delete \) \ + -resize x512 './icon_512x512.png' +cd '..' + +cd "./${OUT_ICON_NAME}_shadow_rounded.iconset/" +convert './icon_512x512@2x.png' \ + \( +clone -resize x16 -write './icon_16x16.png' +delete \) \ + \( +clone -resize x32 -write './icon_16x16@2x.png' +delete \) \ + \( +clone -resize x32 -write './icon_32x32.png' +delete \) \ + \( +clone -resize x64 -write './icon_32x32@2x.png' +delete \) \ + \( +clone -resize x128 -write './icon_128x128.png' +delete \) \ + \( +clone -resize x256 -write './icon_128x128@2x.png' +delete \) \ + \( +clone -resize x256 -write './icon_256x256.png' +delete \) \ + \( +clone -resize x512 -write './icon_256x256@2x.png' +delete \) \ + -resize x512 './icon_512x512.png' +cd '..' + +cd "./${OUT_ICON_NAME}_rounded.iconset/" +convert './icon_512x512@2x.png' \ + \( +clone -resize x16 -write './icon_16x16.png' +delete \) \ + \( +clone -resize x32 -write './icon_16x16@2x.png' +delete \) \ + \( +clone -resize x32 -write './icon_32x32.png' +delete \) \ + \( +clone -resize x64 -write './icon_32x32@2x.png' +delete \) \ + \( +clone -resize x128 -write './icon_128x128.png' +delete \) \ + \( +clone -resize x256 -write './icon_128x128@2x.png' +delete \) \ + \( +clone -resize x256 -write './icon_256x256.png' +delete \) \ + \( +clone -resize x512 -write './icon_256x256@2x.png' +delete \) \ + -resize x512 './icon_512x512.png' +cd '..' + +# Convert to .icns format and remove iconset +iconutil -c icns "./${OUT_ICON_NAME}.iconset" +# rm -r "./${OUT_ICON_NAME}.iconset" + +mkdir icons +mv "./${OUT_ICON_NAME}.icns" "./icons/${OUT_ICON_NAME}.icns" +mv "./${OUT_ICON_NAME}_shadow_rounded.iconset" "./icons/${OUT_ICON_NAME}_shadow_rounded" +mv "./${OUT_ICON_NAME}_rounded.iconset" "./icons/${OUT_ICON_NAME}_rounded" +mv "./${OUT_ICON_NAME}.iconset" "./icons/${OUT_ICON_NAME}" \ No newline at end of file diff --git a/packages/api/package.json b/packages/api/package.json index b6c2f389..538494f8 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -26,6 +26,8 @@ "express": "^4.18.2", "fs-extra": "^11.1.1", "lodash": "^4.17.21", + "plaiceholder": "^3.0.0", + "sharp": "^0.32.5", "superjson": "1.13.1", "zod": "^3.22.2" }, diff --git a/packages/api/src/express.ts b/packages/api/src/express.ts index 7eb604ac..11eb7115 100644 --- a/packages/api/src/express.ts +++ b/packages/api/src/express.ts @@ -6,6 +6,8 @@ import express from "express"; import { readFileSync } from "fs-extra"; import { getPlaiceholder } from "plaiceholder"; +import type { Library } from "@rao-pics/db"; + import { router } from ".."; import { createContext } from "./utils"; @@ -22,6 +24,7 @@ const asyncMiddleware = let server: Server | undefined; let libraryPath: string | undefined; +let library: Library | null; export const startExpressServer = async () => { if (server) return; @@ -30,7 +33,7 @@ export const startExpressServer = async () => { const caller = router.createCaller({}); const config = await caller.config.get(); - const library = await caller.library.get(); + library = await caller.library.get(); const port = config?.serverPort; @@ -63,15 +66,15 @@ export const startExpressServer = async () => { */ app.use("/static/", (req, res, next) => { if (!library) { - return res.status(404).send("library is not defined"); + res.status(404).send("library is not defined"); + } else { + libraryPath = join(library.path, "images"); + express.static(libraryPath, { maxAge: 180 * 1000 * 60 * 60 })( + req, + res, + next, + ); } - - libraryPath = join(library.path, "images"); - express.static(libraryPath, { maxAge: 180 * 1000 * 60 * 60 })( - req, - res, - next, - ); }); /** @@ -130,7 +133,7 @@ export const startExpressServer = async () => { export const updateLibraryPath = async () => { const caller = router.createCaller({}); - const library = await caller.library.get(); + library = await caller.library.get(); if (library?.path) { libraryPath = join(library.path, "images"); diff --git a/packages/api/src/image.ts b/packages/api/src/image.ts index 62a8edc4..cf058300 100644 --- a/packages/api/src/image.ts +++ b/packages/api/src/image.ts @@ -179,6 +179,8 @@ export const image = t.router({ data, }); } + + return null; }), deleteByUnique: t.procedure diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85614cb4..bfee54c8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -128,6 +128,12 @@ importers: '@rao-pics/tsconfig': specifier: ^0.1.0 version: link:../../tooling/typescript + '@sentry/electron': + specifier: ^4.11.0 + version: 4.11.0 + '@sentry/vite-plugin': + specifier: ^2.7.1 + version: 2.7.1 '@types/ip': specifier: ^1.1.0 version: 1.1.0 @@ -240,6 +246,12 @@ importers: lodash: specifier: ^4.17.21 version: 4.17.21 + plaiceholder: + specifier: ^3.0.0 + version: 3.0.0(sharp@0.32.5) + sharp: + specifier: ^0.32.5 + version: 0.32.5 superjson: specifier: 1.13.1 version: 1.13.1 @@ -1641,6 +1653,134 @@ packages: resolution: {integrity: sha512-dT7FOLUCdZmq+AunLqB1Iz+ZH/IIS1Fz2THmKZQ6aFONrQD/BQ5ecJ7g2wGS2OgyUFf4OaLam6/bxmgdOBDqig==} requiresBuild: true + /@sentry-internal/tracing@7.68.0: + resolution: {integrity: sha512-nNKS/q21+Iqzxs2K7T/l3dZi8Z9s/uxsAazpk2AYhFzx9mFnPj1Xfe3dgbFoygNifE+IrpUuldr6D5HQamTDPQ==} + engines: {node: '>=8'} + dependencies: + '@sentry/core': 7.68.0 + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + tslib: 2.6.2 + dev: true + + /@sentry/browser@7.68.0: + resolution: {integrity: sha512-1RIPLzKcBeUeG8CQc4OIRfQ6F1zmGKku1am7P9QTz0bz//Mu7bEjm75DM69LBoUlP/Ab9cQQA3fZFUvrH0j1Tg==} + engines: {node: '>=8'} + dependencies: + '@sentry-internal/tracing': 7.68.0 + '@sentry/core': 7.68.0 + '@sentry/replay': 7.68.0 + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + tslib: 2.6.2 + dev: true + + /@sentry/bundler-plugin-core@2.7.1: + resolution: {integrity: sha512-ZC/B/7FzzgGpux2t54B2ioXudlq60MHMVPaUeuFzWwxmxiArrV4uBXcp18RMW5ns4biik5WBAD72vbsoloBfIQ==} + engines: {node: '>= 14'} + dependencies: + '@sentry/cli': 2.20.7 + '@sentry/node': 7.68.0 + '@sentry/utils': 7.68.0 + dotenv: 16.3.1 + find-up: 5.0.0 + glob: 9.3.2 + magic-string: 0.27.0 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@sentry/cli@2.20.7: + resolution: {integrity: sha512-YaHKEUdsFt59nD8yLvuEGCOZ3/ArirL8GZ/66RkZ8wcD2wbpzOFbzo08Kz4te/Eo3OD5/RdW+1dPaOBgGbrXlA==} + engines: {node: '>= 10'} + hasBin: true + requiresBuild: true + dependencies: + https-proxy-agent: 5.0.1 + node-fetch: 2.7.0 + progress: 2.0.3 + proxy-from-env: 1.1.0 + which: 2.0.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@sentry/core@7.68.0: + resolution: {integrity: sha512-mT3ObBWgvAky/QF3dZy4KBoXbRXbNsD6evn+mYi9UEeIZQ5NpnQYDEp78mapiEjI/TAHZIhTIuaBhj1Jk0qUUA==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + tslib: 2.6.2 + dev: true + + /@sentry/electron@4.11.0: + resolution: {integrity: sha512-NTySgrqXYf9KNPpKutYlrG9NDob3/I8kyd7AHEAxY2d0gcz4EL4O2kmpNAR/DwxeqmqPAnu+UxIva7t9ATa6Bg==} + dependencies: + '@sentry/browser': 7.68.0 + '@sentry/core': 7.68.0 + '@sentry/node': 7.68.0 + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + deepmerge: 4.3.0 + lru_map: 0.3.3 + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@sentry/node@7.68.0: + resolution: {integrity: sha512-gtcHoi6Xu6Iu8MpPgKJA4E0nozqLvYF0fKtt+27T0QBzWioO6lkxSQkKGWMyJGL0AmpLCex0E28fck/rlbt0LA==} + engines: {node: '>=8'} + dependencies: + '@sentry-internal/tracing': 7.68.0 + '@sentry/core': 7.68.0 + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 2.6.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@sentry/replay@7.68.0: + resolution: {integrity: sha512-be8QT2pxcLOTuX6HBRkK0mCVwM97dU5ZLCeofI+xJEWcRnoJdbx00nFwvBXvvoCizbtf4YIMCGwaT2k5LrVxsQ==} + engines: {node: '>=12'} + dependencies: + '@sentry/core': 7.68.0 + '@sentry/types': 7.68.0 + '@sentry/utils': 7.68.0 + dev: true + + /@sentry/types@7.68.0: + resolution: {integrity: sha512-5J2pH1Pjx/029zTm3CNY9MaE8Aui81nG7JCtlMp7uEfQ//9Ja4d4Sliz/kV4ARbkIKUZerSgaRAm3xCy5XOXLg==} + engines: {node: '>=8'} + dev: true + + /@sentry/utils@7.68.0: + resolution: {integrity: sha512-NecnQegvKARyeFmBx7mYmbI17mTvjARWs1nfzY5jhPyNc3Zk4M3bQsgIdnJ1t+jo93UYudlNND7hxhDzjcBAVg==} + engines: {node: '>=8'} + dependencies: + '@sentry/types': 7.68.0 + tslib: 2.6.2 + dev: true + + /@sentry/vite-plugin@2.7.1: + resolution: {integrity: sha512-bZrM06Z+QP/TvPyTYFxpQVugT5rzaFW1jzTnHzUHICz5tgyarY8bhhmYXnI37f6mngkVwDZNAftczbVF2IuFWQ==} + engines: {node: '>= 14'} + dependencies: + '@sentry/bundler-plugin-core': 2.7.1 + unplugin: 1.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -3156,6 +3296,11 @@ packages: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} dev: false + /cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + dev: true + /cookie@0.5.0: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} @@ -3664,6 +3809,11 @@ packages: /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + /deepmerge@4.3.0: + resolution: {integrity: sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og==} + engines: {node: '>=0.10.0'} + dev: true + /default-browser-id@3.0.0: resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} engines: {node: '>=12'} @@ -3848,6 +3998,11 @@ packages: engines: {node: '>=12'} dev: false + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: true + /dotenv@9.0.2: resolution: {integrity: sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==} engines: {node: '>=10'} @@ -4995,6 +5150,16 @@ packages: once: 1.4.0 path-is-absolute: 1.0.1 + /glob@9.3.2: + resolution: {integrity: sha512-BTv/JhKXFEHsErMte/AnfiSv8yYOLLiyH2lTg8vn02O21zWFgHPTfxtgn1QRe7NRgggUhC8hacR2Re94svHqeA==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + fs.realpath: 1.0.0 + minimatch: 7.4.6 + minipass: 4.2.8 + path-scurry: 1.10.1 + dev: true + /global-agent@3.0.0: resolution: {integrity: sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==} engines: {node: '>=10.0'} @@ -6116,6 +6281,17 @@ packages: engines: {node: '>=12'} dev: true + /lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + /magic-string@0.30.2: resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} engines: {node: '>=12'} @@ -6868,6 +7044,13 @@ packages: brace-expansion: 2.0.1 dev: true + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + /minimatch@9.0.3: resolution: {integrity: sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==} engines: {node: '>=16 || 14 >=14.17'} @@ -6924,6 +7107,11 @@ packages: yallist: 4.0.0 dev: true + /minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + dev: true + /minipass@5.0.0: resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} engines: {node: '>=8'} @@ -7204,6 +7392,18 @@ packages: semver: 7.5.4 dev: true + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + /node-gyp@9.4.0: resolution: {integrity: sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg==} engines: {node: ^12.13 || ^14.13 || >=16} @@ -7916,6 +8116,10 @@ packages: ipaddr.js: 1.9.1 dev: false + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true + /pseudomap@1.0.2: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: false @@ -9203,6 +9407,10 @@ packages: engines: {node: '>=6'} dev: true + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + /trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} dev: false @@ -9576,6 +9784,15 @@ packages: engines: {node: '>= 0.8'} dev: false + /unplugin@1.0.1: + resolution: {integrity: sha512-aqrHaVBWW1JVKBHmGo33T5TxeL0qWzfvjWokObHA9bYmN7eNDkwOxmLjhioHl9878qDFMAaT51XNroRyuz7WxA==} + dependencies: + acorn: 8.10.0 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + dev: true + /untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -9872,6 +10089,26 @@ packages: resolution: {integrity: sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==} dev: false + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} dependencies: diff --git a/themes/tiga-basic/public/icons b/themes/tiga-basic/public/icons new file mode 120000 index 00000000..7c625046 --- /dev/null +++ b/themes/tiga-basic/public/icons @@ -0,0 +1 @@ +/Users/meetqy/Desktop/me/electron-vite/icons/icons \ No newline at end of file diff --git a/themes/tiga-basic/public/manifest.json b/themes/tiga-basic/public/manifest.json new file mode 100644 index 00000000..a879203a --- /dev/null +++ b/themes/tiga-basic/public/manifest.json @@ -0,0 +1,16 @@ +{ + "short_name": "Rao Pics", + "name": "Tiga Basic For Rao Pics", + "icons": [ + { + "src": "/icons/icon/icon_512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#FFFFFF", + "background_color": "#FFFFFF", + "start_url": "/", + "display": "standalone", + "orientation": "portrait" +} diff --git a/themes/tiga-basic/public/next.svg b/themes/tiga-basic/public/next.svg deleted file mode 100644 index 5174b28c..00000000 --- a/themes/tiga-basic/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/themes/tiga-basic/public/vercel.svg b/themes/tiga-basic/public/vercel.svg deleted file mode 100644 index d2f84222..00000000 --- a/themes/tiga-basic/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/themes/tiga-basic/src/pages/_app.tsx b/themes/tiga-basic/src/pages/_app.tsx index 6fc0f85b..c19eb4e4 100644 --- a/themes/tiga-basic/src/pages/_app.tsx +++ b/themes/tiga-basic/src/pages/_app.tsx @@ -1,11 +1,33 @@ import type { AppProps } from "next/app"; +import Head from "next/head"; import "~/styles/globals.css"; import { trpc } from "~/utils/trpc"; function App({ Component, pageProps }: AppProps) { - return ; + return ( + <> + + + + + + + + + + + + + + + + Tiga Basic for Rao Pics + + + + ); } export default trpc.withTRPC(App); diff --git a/themes/tiga-basic/src/pages/index.tsx b/themes/tiga-basic/src/pages/index.tsx index afd85030..5f14be78 100644 --- a/themes/tiga-basic/src/pages/index.tsx +++ b/themes/tiga-basic/src/pages/index.tsx @@ -65,7 +65,7 @@ function Home() { return (
{pages?.map((page) => { @@ -103,7 +103,11 @@ function Home() { layout="rows" photos={photos} breakpoints={[640, 768, 1024, 1280, 1536]} - spacing={16} + spacing={(containerWidth) => { + if (containerWidth < 640) return 12; + + return 16; + }} targetRowHeight={(containerWidth) => { if (containerWidth < 640) return containerWidth / 1; if (containerWidth < 768) return containerWidth / 1; diff --git a/themes/tiga-basic/src/styles/globals.css b/themes/tiga-basic/src/styles/globals.css index b5c61c95..aee1bf56 100644 --- a/themes/tiga-basic/src/styles/globals.css +++ b/themes/tiga-basic/src/styles/globals.css @@ -1,3 +1,7 @@ @tailwind base; @tailwind components; @tailwind utilities; + +body { + @apply bg-base-100; +}