diff --git a/.env.example b/.env.example new file mode 100644 index 000000000..a5a87ff9b --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +PUBLIC_APPWRITE_PROJECT_INIT_ID= +PUBLIC_APPWRITE_PROJECT_ID= +PUBLIC_APPWRITE_DB_MAIN_ID= +PUBLIC_APPWRITE_COL_THREADS_ID= +PUBLIC_APPWRITE_COL_MESSAGES_ID= +PUBLIC_APPWRITE_FN_TLDR_ID= \ No newline at end of file diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml index 7264e017b..697ddd9b5 100644 --- a/.github/workflows/production.yml +++ b/.github/workflows/production.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.actor }} @@ -54,6 +54,12 @@ jobs: git checkout ${{ env.TAG }} rm -f .env + echo "PUBLIC_APPWRITE_PROJECT_INIT_ID=${{ env.PUBLIC_APPWRITE_PROJECT_INIT_ID }}" >> .env + echo "PUBLIC_APPWRITE_PROJECT_ID=${{ env.PUBLIC_APPWRITE_PROJECT_ID }}" >> .env + echo "PUBLIC_APPWRITE_DB_MAIN_ID=${{ env.PUBLIC_APPWRITE_DB_MAIN_ID }}" >> .env + echo "PUBLIC_APPWRITE_COL_THREADS_ID=${{ env.PUBLIC_APPWRITE_COL_THREADS_ID }}" >> .env + echo "PUBLIC_APPWRITE_COL_MESSAGES_ID=${{ env.PUBLIC_APPWRITE_COL_MESSAGES_ID }}" >> .env + echo "PUBLIC_APPWRITE_FN_TLDR_ID=${{ env.PUBLIC_APPWRITE_FN_TLDR_ID }}" >> .env echo "_APP_VERSION=${{ env.TAG }}" >> .env echo "_APP_DOMAIN=${{ secrets.PRD_APP_DOMAIN }}" >> .env echo "_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${{ secrets.APP_SYSTEM_SECURITY_EMAIL_ADDRESS }}" >> .env diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index a78c5f402..83d0ba86d 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -19,7 +19,7 @@ jobs: uses: actions/checkout@v2 - name: Login to DockerHub - uses: docker/login-action@v1 + uses: docker/login-action@v1 with: registry: ghcr.io username: ${{ github.actor }} @@ -55,6 +55,12 @@ jobs: git checkout ${{ env.TAG }} rm -f .env + echo "PUBLIC_APPWRITE_PROJECT_INIT_ID=${{ env.PUBLIC_APPWRITE_PROJECT_INIT_ID }}" >> .env + echo "PUBLIC_APPWRITE_PROJECT_ID=${{ env.PUBLIC_APPWRITE_PROJECT_ID }}" >> .env + echo "PUBLIC_APPWRITE_DB_MAIN_ID=${{ env.PUBLIC_APPWRITE_DB_MAIN_ID }}" >> .env + echo "PUBLIC_APPWRITE_COL_THREADS_ID=${{ env.PUBLIC_APPWRITE_COL_THREADS_ID }}" >> .env + echo "PUBLIC_APPWRITE_COL_MESSAGES_ID=${{ env.PUBLIC_APPWRITE_COL_MESSAGES_ID }}" >> .env + echo "PUBLIC_APPWRITE_FN_TLDR_ID=${{ env.PUBLIC_APPWRITE_FN_TLDR_ID }}" >> .env echo "_APP_VERSION=${{ env.TAG }}" >> .env echo "_APP_DOMAIN=${{ secrets.STG_APP_DOMAIN }}" >> .env echo "_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=${{ secrets.APP_SYSTEM_SECURITY_EMAIL_ADDRESS }}" >> .env diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 11c5d7290..feb972944 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -37,4 +37,10 @@ jobs: - name: Build Website env: NODE_OPTIONS: '--max_old_space_size=4096' + PUBLIC_APPWRITE_PROJECT_INIT_ID: ${{ secrets.PUBLIC_APPWRITE_PROJECT_INIT_ID }} + PUBLIC_APPWRITE_PROJECT_ID: ${{ secrets.PUBLIC_APPWRITE_PROJECT_ID }} + PUBLIC_APPWRITE_DB_MAIN_ID: ${{ secrets.PUBLIC_APPWRITE_DB_MAIN_ID }} + PUBLIC_APPWRITE_COL_THREADS_ID: ${{ secrets.PUBLIC_APPWRITE_COL_THREADS_ID }} + PUBLIC_APPWRITE_COL_MESSAGES_ID: ${{ secrets.PUBLIC_APPWRITE_COL_MESSAGES_ID }} + PUBLIC_APPWRITE_FN_TLDR_ID: ${{ secrets.PUBLIC_APPWRITE_FN_TLDR_ID }} run: pnpm run build diff --git a/.gitignore b/.gitignore index f3eaf11ca..457b4a4bd 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,9 @@ node_modules /package .env .env.* +.envrc !.env.example vite.config.js.timestamp-* vite.config.ts.timestamp-* -package-lock.json \ No newline at end of file +package-lock.json +.tool-versions \ No newline at end of file diff --git a/docker/production.yml b/docker/production.yml index 98a138793..8cf3d604a 100644 --- a/docker/production.yml +++ b/docker/production.yml @@ -60,6 +60,13 @@ services: <<: *x-logging networks: - cloud + environment: + - PUBLIC_APPWRITE_PROJECT_INIT_ID + - PUBLIC_APPWRITE_PROJECT_ID + - PUBLIC_APPWRITE_DB_MAIN_ID + - PUBLIC_APPWRITE_COL_THREADS_ID + - PUBLIC_APPWRITE_COL_MESSAGES_ID + - PUBLIC_APPWRITE_FN_TLDR_ID deploy: <<: *x-update-config mode: replicated @@ -68,7 +75,7 @@ services: max_replicas_per_node: 2 constraints: - node.role == worker - preferences: + preferences: - spread: node.role == worker labels: - traefik.enable=true @@ -94,7 +101,7 @@ services: environment: - TIME_BETWEEN_RUNS=3600 - UNUSED_TIME=6h - + sematext-agent: image: sematext/agent:latest environment: diff --git a/docker/stage.yml b/docker/stage.yml index 5d2be7ef0..13dced3a7 100644 --- a/docker/stage.yml +++ b/docker/stage.yml @@ -61,6 +61,13 @@ services: <<: *x-logging networks: - cloud + environment: + - PUBLIC_APPWRITE_PROJECT_INIT_ID + - PUBLIC_APPWRITE_PROJECT_ID + - PUBLIC_APPWRITE_DB_MAIN_ID + - PUBLIC_APPWRITE_COL_THREADS_ID + - PUBLIC_APPWRITE_COL_MESSAGES_ID + - PUBLIC_APPWRITE_FN_TLDR_ID deploy: <<: *x-update-config mode: replicated @@ -69,7 +76,7 @@ services: max_replicas_per_node: 2 constraints: - node.role == worker - preferences: + preferences: - spread: node.role == worker labels: - traefik.enable=true @@ -96,7 +103,7 @@ services: - RUN_ON_STARTUP=true volumes: - /var/run/docker.sock:/var/run/docker.sock - + sematext-agent: image: sematext/agent:latest environment: diff --git a/package.json b/package.json index 31b218229..db1cc5089 100644 --- a/package.json +++ b/package.json @@ -20,18 +20,19 @@ }, "devDependencies": { "@melt-ui/pp": "^0.1.4", - "@melt-ui/svelte": "^0.60.2", + "@melt-ui/svelte": "^0.65.0", "@playwright/test": "^1.40.0", "@sveltejs/adapter-node": "^1.3.1", "@sveltejs/adapter-static": "^2.0.3", "@sveltejs/enhanced-img": "^0.1.2", - "@sveltejs/kit": "^1.27.6", + "@sveltejs/kit": "^1.27.7", "@types/compression": "^1.7.5", "@types/glob": "^8.1.0", "@types/markdown-it": "^13.0.7", "@types/morgan": "^1.9.9", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "appwrite": "^13.0.1", "eslint": "^8.54.0", "eslint-config-prettier": "^8.10.0", "eslint-plugin-svelte": "^2.35.1", @@ -40,11 +41,12 @@ "oslllo-svg-fixer": "^3.0.0", "prettier": "^2.8.8", "prettier-plugin-svelte": "^2.10.1", - "sass": "^1.69.5", + "sass": "^1.69.7", "svelte": "^4.2.7", "svelte-check": "^3.6.0", "svelte-markdoc-preprocess": "^1.1.3", "svelte-sequential-preprocessor": "^2.0.1", + "sveltekit-search-params": "^1.0.16", "svgo": "^3.0.4", "svgtofont": "^4.0.0", "tslib": "^2.6.2", @@ -66,6 +68,7 @@ "markdown-it": "^13.0.2", "meilisearch": "^0.35.1", "motion": "^10.16.4", - "sharp": "^0.32.6" + "sharp": "^0.32.6", + "svelte-markdown": "^0.4.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 654ea7d0c..b991926d4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,29 +38,32 @@ dependencies: sharp: specifier: ^0.32.6 version: 0.32.6 + svelte-markdown: + specifier: ^0.4.0 + version: 0.4.1(svelte@4.2.7) devDependencies: '@melt-ui/pp': specifier: ^0.1.4 - version: 0.1.4(@melt-ui/svelte@0.60.2)(svelte@4.2.7) + version: 0.1.4(@melt-ui/svelte@0.65.2)(svelte@4.2.7) '@melt-ui/svelte': - specifier: ^0.60.2 - version: 0.60.2(svelte@4.2.7) + specifier: ^0.65.0 + version: 0.65.2(svelte@4.2.7) '@playwright/test': specifier: ^1.40.0 version: 1.40.0 '@sveltejs/adapter-node': specifier: ^1.3.1 - version: 1.3.1(@sveltejs/kit@1.27.6) + version: 1.3.1(@sveltejs/kit@1.30.3) '@sveltejs/adapter-static': specifier: ^2.0.3 - version: 2.0.3(@sveltejs/kit@1.27.6) + version: 2.0.3(@sveltejs/kit@1.30.3) '@sveltejs/enhanced-img': specifier: ^0.1.2 version: 0.1.5(svelte@4.2.7) '@sveltejs/kit': - specifier: ^1.27.6 - version: 1.27.6(svelte@4.2.7)(vite@4.5.1) + specifier: ^1.27.7 + version: 1.30.3(svelte@4.2.7)(vite@4.5.1) '@types/compression': specifier: ^1.7.5 version: 1.7.5 @@ -79,6 +82,9 @@ devDependencies: '@typescript-eslint/parser': specifier: ^5.62.0 version: 5.62.0(eslint@8.54.0)(typescript@5.3.2) + appwrite: + specifier: ^13.0.1 + version: 13.0.1 eslint: specifier: ^8.54.0 version: 8.54.0 @@ -104,20 +110,23 @@ devDependencies: specifier: ^2.10.1 version: 2.10.1(prettier@2.8.8)(svelte@4.2.7) sass: - specifier: ^1.69.5 - version: 1.69.5 + specifier: ^1.69.7 + version: 1.69.7 svelte: specifier: ^4.2.7 version: 4.2.7 svelte-check: specifier: ^3.6.0 - version: 3.6.0(postcss@8.4.31)(sass@1.69.5)(svelte@4.2.7) + version: 3.6.0(postcss@8.4.31)(sass@1.69.7)(svelte@4.2.7) svelte-markdoc-preprocess: specifier: ^1.1.3 version: 1.1.3 svelte-sequential-preprocessor: specifier: ^2.0.1 version: 2.0.1 + sveltekit-search-params: + specifier: ^1.0.16 + version: 1.1.1(@sveltejs/kit@1.30.3)(svelte@4.2.7) svgo: specifier: ^3.0.4 version: 3.0.4 @@ -132,7 +141,7 @@ devDependencies: version: 5.3.2 vite: specifier: ^4.5.1 - version: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + version: 4.5.1(@types/node@20.9.3)(sass@1.69.7) vite-plugin-dynamic-import: specifier: ^1.5.0 version: 1.5.0 @@ -141,7 +150,7 @@ devDependencies: version: 1.1.7(vite@4.5.1) vitest: specifier: ^0.32.4 - version: 0.32.4(sass@1.69.5) + version: 0.32.4(sass@1.69.7) packages: @@ -156,7 +165,6 @@ packages: dependencies: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.20 - dev: true /@appwrite.io/pink-icons@0.1.0-next.9: resolution: {integrity: sha512-6t4Pqt/xugjpJQyaMx1u/7Gt9CkW5iItDAgUKcIMm84E4NbDJq8ZdAhhvctGQQppKUgHDPi+6x1XveUUd7tdbg==} @@ -462,6 +470,12 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@internationalized/date@3.5.1: + resolution: {integrity: sha512-LUQIfwU9e+Fmutc/DpRTGXSdgYZLBegi4wygCWDSVmUdLTaMHsQyASDiJtREwanwKuQLq0hY76fCJ9J/9I2xOQ==} + dependencies: + '@swc/helpers': 0.5.3 + dev: true + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -863,28 +877,23 @@ packages: '@jridgewell/set-array': 1.1.2 '@jridgewell/sourcemap-codec': 1.4.15 '@jridgewell/trace-mapping': 0.3.20 - dev: true /@jridgewell/resolve-uri@3.1.1: resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/set-array@1.1.2: resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} engines: {node: '>=6.0.0'} - dev: true /@jridgewell/sourcemap-codec@1.4.15: resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} - dev: true /@jridgewell/trace-mapping@0.3.20: resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==} dependencies: '@jridgewell/resolve-uri': 3.1.1 '@jridgewell/sourcemap-codec': 1.4.15 - dev: true /@lit-labs/ssr-dom-shim@1.1.2: resolution: {integrity: sha512-jnOD+/+dSrfTWYfSXBXlo5l5f0q1UuJo3tkbMDCYA2lKUYq79jaxqtGEvnRoh049nt1vdo1+45RinipU6FGY2g==} @@ -911,25 +920,26 @@ packages: '@types/markdown-it': 12.2.3 dev: true - /@melt-ui/pp@0.1.4(@melt-ui/svelte@0.60.2)(svelte@4.2.7): + /@melt-ui/pp@0.1.4(@melt-ui/svelte@0.65.2)(svelte@4.2.7): resolution: {integrity: sha512-zR+Kl3CZJPJBHW8V7YcdQCMI/dVcnW9Ct3yGbVaIywYVStVRS7F9uEDOea3xLLT2WTGodQePzPlUn53yKFu87g==} engines: {pnpm: '>=8.6.3'} peerDependencies: '@melt-ui/svelte': '>= 0.29.0' svelte: ^3.55.0 || ^4.0.0 || ^5.0.0-next.1 dependencies: - '@melt-ui/svelte': 0.60.2(svelte@4.2.7) + '@melt-ui/svelte': 0.65.2(svelte@4.2.7) estree-walker: 3.0.3 svelte: 4.2.7 dev: true - /@melt-ui/svelte@0.60.2(svelte@4.2.7): - resolution: {integrity: sha512-dBGW7dIDBMYchCH0Fx9byqrCYtpkXX1QUGXdv1e2aQE20bDCrQqwVSV0/1iWuJVYyFeo2xUdr0/LVZJ6lOw4mg==} + /@melt-ui/svelte@0.65.2(svelte@4.2.7): + resolution: {integrity: sha512-BpsSl9Bjp1++8U3+LaDOFUoX/PFQ9N7QWFhlFdUEZduhrbVyU70v9A459SKrQ+esFSjvh1AvqJYkMAUJXJlAmQ==} peerDependencies: svelte: '>=3 <5' dependencies: '@floating-ui/core': 1.5.0 '@floating-ui/dom': 1.5.3 + '@internationalized/date': 3.5.1 dequal: 2.0.3 focus-trap: 7.5.4 nanoid: 4.0.2 @@ -1254,7 +1264,7 @@ packages: lit: 2.8.0 dev: false - /@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.27.6): + /@sveltejs/adapter-node@1.3.1(@sveltejs/kit@1.30.3): resolution: {integrity: sha512-A0VgRQDCDPzdLNoiAbcOxGw4zT1Mc+n1LwT1OmO350R7WxrEqdMUChPPOd1iMfIDWlP4ie6E2d/WQf5es2d4Zw==} peerDependencies: '@sveltejs/kit': ^1.0.0 @@ -1262,16 +1272,16 @@ packages: '@rollup/plugin-commonjs': 25.0.7(rollup@3.29.4) '@rollup/plugin-json': 6.0.1(rollup@3.29.4) '@rollup/plugin-node-resolve': 15.2.3(rollup@3.29.4) - '@sveltejs/kit': 1.27.6(svelte@4.2.7)(vite@4.5.1) + '@sveltejs/kit': 1.30.3(svelte@4.2.7)(vite@4.5.1) rollup: 3.29.4 dev: true - /@sveltejs/adapter-static@2.0.3(@sveltejs/kit@1.27.6): + /@sveltejs/adapter-static@2.0.3(@sveltejs/kit@1.30.3): resolution: {integrity: sha512-VUqTfXsxYGugCpMqQv1U0LIdbR3S5nBkMMDmpjGVJyM6Q2jHVMFtdWJCkeHMySc6mZxJ+0eZK3T7IgmUCDrcUQ==} peerDependencies: '@sveltejs/kit': ^1.5.0 dependencies: - '@sveltejs/kit': 1.27.6(svelte@4.2.7)(vite@4.5.1) + '@sveltejs/kit': 1.30.3(svelte@4.2.7)(vite@4.5.1) dev: true /@sveltejs/enhanced-img@0.1.5(svelte@4.2.7): @@ -1285,8 +1295,8 @@ packages: - svelte dev: true - /@sveltejs/kit@1.27.6(svelte@4.2.7)(vite@4.5.1): - resolution: {integrity: sha512-GsjTkMbKzXdbeRg0tk8S7HNShQ4879ftRr0ZHaZfjbig1xQwG57Bvcm9U9/mpLJtCapLbLWUnygKrgcLISLC8A==} + /@sveltejs/kit@1.30.3(svelte@4.2.7)(vite@4.5.1): + resolution: {integrity: sha512-0DzVXfU4h+tChFvoc8C61IqErCyskD4ydSIDjpKS2lYlEzIYrtYrY7juSqACFxqcvZAnOEXvSY+zZ8br0+ZMMg==} engines: {node: ^16.14 || >=18} hasBin: true requiresBuild: true @@ -1308,7 +1318,7 @@ packages: svelte: 4.2.7 tiny-glob: 0.2.9 undici: 5.26.5 - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) transitivePeerDependencies: - supports-color dev: true @@ -1324,7 +1334,7 @@ packages: '@sveltejs/vite-plugin-svelte': 2.5.2(svelte@4.2.7)(vite@4.5.1) debug: 4.3.4 svelte: 4.2.7 - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) transitivePeerDependencies: - supports-color dev: true @@ -1343,12 +1353,18 @@ packages: magic-string: 0.30.5 svelte: 4.2.7 svelte-hmr: 0.15.3(svelte@4.2.7) - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) vitefu: 0.2.5(vite@4.5.1) transitivePeerDependencies: - supports-color dev: true + /@swc/helpers@0.5.3: + resolution: {integrity: sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==} + dependencies: + tslib: 2.6.2 + dev: true + /@tokenizer/token@0.3.0: resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} dev: true @@ -1408,7 +1424,6 @@ packages: /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} - dev: true /@types/express-serve-static-core@4.17.41: resolution: {integrity: sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA==} @@ -1476,6 +1491,10 @@ packages: '@types/mdurl': 1.0.5 dev: true + /@types/marked@5.0.2: + resolution: {integrity: sha512-OucS4KMHhFzhz27KxmWg7J+kIYqyqoW5kdIEI319hqARQQUTqhao3M/F+uFnDXD0Rg72iDDZxZNxq5gvctmLlg==} + dev: false + /@types/mdurl@1.0.5: resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} dev: true @@ -1781,7 +1800,6 @@ packages: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} @@ -1864,6 +1882,15 @@ packages: picomatch: 2.3.1 dev: true + /appwrite@13.0.1: + resolution: {integrity: sha512-kdOLB5Qbr2beQW72diA/dx8L16LywHcQV1H6oqgGtf64Mo6LsvyIM1hEVxWmFLwAXMaOtsqb7Mcs4+oQHo+WmQ==} + dependencies: + cross-fetch: 3.1.5 + isomorphic-form-data: 2.0.0 + transitivePeerDependencies: + - encoding + dev: true + /aproba@2.0.0: resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} dev: true @@ -1883,7 +1910,6 @@ packages: resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} dependencies: dequal: 2.0.3 - dev: true /arr-diff@4.0.0: resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} @@ -1927,6 +1953,10 @@ packages: resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} dev: true + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + /atob@2.1.2: resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} engines: {node: '>= 4.5.0'} @@ -1950,7 +1980,6 @@ packages: resolution: {integrity: sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==} dependencies: dequal: 2.0.3 - dev: true /b4a@1.6.4: resolution: {integrity: sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==} @@ -2276,7 +2305,6 @@ packages: acorn: 8.11.2 estree-walker: 3.0.3 periscopic: 3.1.0 - dev: true /collection-visit@1.0.0: resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} @@ -2318,6 +2346,13 @@ packages: hasBin: true dev: true + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + /commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -2416,6 +2451,14 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true + /cross-fetch@3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + dependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: true + /cross-fetch@3.1.8: resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} dependencies: @@ -2457,7 +2500,6 @@ packages: dependencies: mdn-data: 2.0.30 source-map-js: 1.0.2 - dev: true /css-what@6.1.0: resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} @@ -2579,6 +2621,11 @@ packages: slash: 3.0.0 dev: true + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} dev: true @@ -2591,7 +2638,6 @@ packages: /dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} - dev: true /destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} @@ -2938,7 +2984,6 @@ packages: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} dependencies: '@types/estree': 1.0.5 - dev: true /esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} @@ -3177,6 +3222,15 @@ packages: signal-exit: 4.1.0 dev: true + /form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -3759,7 +3813,6 @@ packages: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} dependencies: '@types/estree': 1.0.5 - dev: true /is-windows@1.0.2: resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} @@ -3786,6 +3839,12 @@ packages: engines: {node: '>=0.10.0'} dev: true + /isomorphic-form-data@2.0.0: + resolution: {integrity: sha512-TYgVnXWeESVmQSg4GLVbalmQ+B4NPi/H4eWxqALKj63KsUrcu301YDjBqaOw3h+cbak7Na4Xyps3BiptHtxTfg==} + dependencies: + form-data: 2.5.1 + dev: true + /jackspeak@2.3.6: resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} engines: {node: '>=14'} @@ -3965,7 +4024,6 @@ packages: /locate-character@3.0.0: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} - dev: true /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -4020,7 +4078,6 @@ packages: engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 - dev: true /make-fetch-happen@10.2.1: resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} @@ -4070,6 +4127,12 @@ packages: uc.micro: 1.0.6 dev: false + /marked@5.1.2: + resolution: {integrity: sha512-ahRPGXJpjMjwSOlBoTMZAK7ATXkli5qCPxZ21TG44rx1KEo44bii4ekgTDQPNRQ4Kh7JMb9Ub1PVk1NxRSsorg==} + engines: {node: '>= 16'} + hasBin: true + dev: false + /maxstache-stream@1.0.4: resolution: {integrity: sha512-v8qlfPN0pSp7bdSoLo1NTjG43GXGqk5W2NWFnOCq2GlmFFqebGzPCjLKSbShuqIOVorOtZSAy7O/S1OCCRONUw==} dependencies: @@ -4089,7 +4152,6 @@ packages: /mdn-data@2.0.30: resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} - dev: true /mdurl@1.0.1: resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} @@ -4158,14 +4220,12 @@ packages: /mime-db@1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - dev: false /mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} dependencies: mime-db: 1.52.0 - dev: false /mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -4428,6 +4488,18 @@ packages: /node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + /node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + 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-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -4748,7 +4820,6 @@ packages: '@types/estree': 1.0.5 estree-walker: 3.0.3 is-reference: 3.0.2 - dev: true /phin@2.9.3: resolution: {integrity: sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==} @@ -5182,8 +5253,8 @@ packages: rimraf: 2.7.1 dev: true - /sass@1.69.5: - resolution: {integrity: sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==} + /sass@1.69.7: + resolution: {integrity: sha512-rzj2soDeZ8wtE2egyLXgOOHQvaC2iosZrkF6v3EUG+tBwEvhqUCzm0VP3k9gHF9LXbSrRhT5SksoI56Iw8NPnQ==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -5413,7 +5484,6 @@ packages: /source-map-js@1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} - dev: true /source-map-resolve@0.5.3: resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} @@ -5582,7 +5652,7 @@ packages: engines: {node: '>= 0.4'} dev: true - /svelte-check@3.6.0(postcss@8.4.31)(sass@1.69.5)(svelte@4.2.7): + /svelte-check@3.6.0(postcss@8.4.31)(sass@1.69.7)(svelte@4.2.7): resolution: {integrity: sha512-8VfqhfuRJ1sKW+o8isH2kPi0RhjXH1nNsIbCFGyoUHG+ZxVxHYRKcb+S8eaL/1tyj3VGvWYx3Y5+oCUsJgnzcw==} hasBin: true peerDependencies: @@ -5595,7 +5665,7 @@ packages: picocolors: 1.0.0 sade: 1.8.1 svelte: 4.2.7 - svelte-preprocess: 5.1.0(postcss@8.4.31)(sass@1.69.5)(svelte@4.2.7)(typescript@5.3.2) + svelte-preprocess: 5.1.0(postcss@8.4.31)(sass@1.69.7)(svelte@4.2.7)(typescript@5.3.2) typescript: 5.3.2 transitivePeerDependencies: - '@babel/core' @@ -5649,6 +5719,16 @@ packages: - react dev: true + /svelte-markdown@0.4.1(svelte@4.2.7): + resolution: {integrity: sha512-pOlLY6EruKJaWI9my/2bKX8PdTeP5CM0s4VMmwmC2prlOkjAf+AOmTM4wW/l19Y6WZ87YmP8+ZCJCCwBChWjYw==} + peerDependencies: + svelte: ^4.0.0 + dependencies: + '@types/marked': 5.0.2 + marked: 5.1.2 + svelte: 4.2.7 + dev: false + /svelte-parse-markup@0.1.2(svelte@4.2.7): resolution: {integrity: sha512-DycY7DJr7VqofiJ63ut1/NEG92HrWWL56VWITn/cJCu+LlZhMoBkBXT4opUitPEEwbq1nMQbv4vTKUfbOqIW1g==} peerDependencies: @@ -5657,7 +5737,7 @@ packages: svelte: 4.2.7 dev: true - /svelte-preprocess@5.1.0(postcss@8.4.31)(sass@1.69.5)(svelte@4.2.7)(typescript@5.3.2): + /svelte-preprocess@5.1.0(postcss@8.4.31)(sass@1.69.7)(svelte@4.2.7)(typescript@5.3.2): resolution: {integrity: sha512-EkErPiDzHAc0k2MF5m6vBNmRUh338h2myhinUw/xaqsLs7/ZvsgREiLGj03VrSzbY/TB5ZXgBOsKraFee5yceA==} engines: {node: '>= 14.10.0'} requiresBuild: true @@ -5699,7 +5779,7 @@ packages: detect-indent: 6.1.0 magic-string: 0.27.0 postcss: 8.4.31 - sass: 1.69.5 + sass: 1.69.7 sorcery: 0.11.0 strip-indent: 3.0.0 svelte: 4.2.7 @@ -5731,6 +5811,15 @@ packages: locate-character: 3.0.0 magic-string: 0.30.5 periscopic: 3.1.0 + + /sveltekit-search-params@1.1.1(@sveltejs/kit@1.30.3)(svelte@4.2.7): + resolution: {integrity: sha512-TVmCa50Cnyryt8UPeFZAE8gMsO80h2kXr531Um0VJaMKK24ZvdR4qbHWyLew9U4d5Flw1w3SbyHWTbLiUGPC7w==} + peerDependencies: + '@sveltejs/kit': ^1.0.0 || ^2.0.0 + svelte: ^3.55.0 || ^4.0.0 || ^5.0.0 + dependencies: + '@sveltejs/kit': 1.30.3(svelte@4.2.7)(vite@4.5.1) + svelte: 4.2.7 dev: true /svg-pathdata@6.0.3: @@ -5977,7 +6066,6 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: false /ts-interface-checker@0.1.13: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} @@ -6177,7 +6265,7 @@ packages: - rollup dev: true - /vite-node@0.32.4(@types/node@20.9.3)(sass@1.69.5): + /vite-node@0.32.4(@types/node@20.9.3)(sass@1.69.7): resolution: {integrity: sha512-L2gIw+dCxO0LK14QnUMoqSYpa9XRGnTTTDjW2h19Mr+GR0EFj4vx52W41gFXfMLqpA00eK4ZjOVYo1Xk//LFEw==} engines: {node: '>=v14.18.0'} hasBin: true @@ -6187,7 +6275,7 @@ packages: mlly: 1.4.2 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) transitivePeerDependencies: - '@types/node' - less @@ -6216,10 +6304,10 @@ packages: dependencies: ansi-colors: 4.1.3 pathe: 1.1.1 - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) dev: true - /vite@4.5.1(@types/node@20.9.3)(sass@1.69.5): + /vite@4.5.1(@types/node@20.9.3)(sass@1.69.7): resolution: {integrity: sha512-AXXFaAJ8yebyqzoNB9fu2pHoo/nWX+xZlaRwoeYUxEqBO+Zj4msE5G+BhGBll9lYEKv9Hfks52PAF2X7qDYXQA==} engines: {node: ^14.18.0 || >=16.0.0} hasBin: true @@ -6251,7 +6339,7 @@ packages: esbuild: 0.18.20 postcss: 8.4.31 rollup: 3.29.4 - sass: 1.69.5 + sass: 1.69.7 optionalDependencies: fsevents: 2.3.3 dev: true @@ -6264,10 +6352,10 @@ packages: vite: optional: true dependencies: - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) dev: true - /vitest@0.32.4(sass@1.69.5): + /vitest@0.32.4(sass@1.69.7): resolution: {integrity: sha512-3czFm8RnrsWwIzVDu/Ca48Y/M+qh3vOnF16czJm98Q/AN1y3B6PBsyV8Re91Ty5s7txKNjEhpgtGPcfdbh2MZg==} engines: {node: '>=v14.18.0'} hasBin: true @@ -6319,8 +6407,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.5.0 - vite: 4.5.1(@types/node@20.9.3)(sass@1.69.5) - vite-node: 0.32.4(@types/node@20.9.3)(sass@1.69.5) + vite: 4.5.1(@types/node@20.9.3)(sass@1.69.7) + vite-node: 0.32.4(@types/node@20.9.3)(sass@1.69.7) why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -6334,14 +6422,12 @@ packages: /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: false /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: false /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} diff --git a/src/hooks/redirects.json b/src/hooks/redirects.json index 2e8b3ecb2..29ebcdbc0 100644 --- a/src/hooks/redirects.json +++ b/src/hooks/redirects.json @@ -642,7 +642,7 @@ { "link": "/docs/models/runtime", "redirect": "/docs/references/cloud/models/runtime" - }, + }, { "link": "/docs/installation", "redirect": "/docs/advanced/self-hosting" @@ -659,5 +659,4 @@ "link": "/policy/privacy", "redirect": "/privacy" } - ] diff --git a/src/icons/optimized/ext-link.svg b/src/icons/optimized/ext-link.svg new file mode 100644 index 000000000..eb13a4883 --- /dev/null +++ b/src/icons/optimized/ext-link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/optimized/message.svg b/src/icons/optimized/message.svg new file mode 100644 index 000000000..ec7c1a554 --- /dev/null +++ b/src/icons/optimized/message.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/icons/output/_variables.scss b/src/icons/output/_variables.scss index 3db5c407a..ac209cbbe 100644 --- a/src/icons/output/_variables.scss +++ b/src/icons/output/_variables.scss @@ -17,26 +17,28 @@ $aw-icon-dark: "\ea10"; $aw-icon-discord: "\ea11"; $aw-icon-divider-vertical: "\ea12"; $aw-icon-download: "\ea13"; -$aw-icon-github: "\ea14"; -$aw-icon-google: "\ea15"; -$aw-icon-hamburger-menu: "\ea16"; -$aw-icon-light: "\ea17"; -$aw-icon-linkedin: "\ea18"; -$aw-icon-location: "\ea19"; -$aw-icon-logout-left: "\ea1a"; -$aw-icon-logout-right: "\ea1b"; -$aw-icon-microsoft: "\ea1c"; -$aw-icon-minus: "\ea1d"; -$aw-icon-nuxt: "\ea1e"; -$aw-icon-platform: "\ea1f"; -$aw-icon-plus: "\ea20"; -$aw-icon-product-hunt: "\ea21"; -$aw-icon-refine: "\ea22"; -$aw-icon-rest: "\ea23"; -$aw-icon-search: "\ea24"; -$aw-icon-star: "\ea25"; -$aw-icon-system: "\ea26"; -$aw-icon-twitter: "\ea27"; -$aw-icon-vue: "\ea28"; -$aw-icon-x: "\ea29"; -$aw-icon-youtube: "\ea2a"; +$aw-icon-ext-link: "\ea14"; +$aw-icon-github: "\ea15"; +$aw-icon-google: "\ea16"; +$aw-icon-hamburger-menu: "\ea17"; +$aw-icon-light: "\ea18"; +$aw-icon-linkedin: "\ea19"; +$aw-icon-location: "\ea1a"; +$aw-icon-logout-left: "\ea1b"; +$aw-icon-logout-right: "\ea1c"; +$aw-icon-message: "\ea1d"; +$aw-icon-microsoft: "\ea1e"; +$aw-icon-minus: "\ea1f"; +$aw-icon-nuxt: "\ea20"; +$aw-icon-platform: "\ea21"; +$aw-icon-plus: "\ea22"; +$aw-icon-product-hunt: "\ea23"; +$aw-icon-refine: "\ea24"; +$aw-icon-rest: "\ea25"; +$aw-icon-search: "\ea26"; +$aw-icon-star: "\ea27"; +$aw-icon-system: "\ea28"; +$aw-icon-twitter: "\ea29"; +$aw-icon-vue: "\ea2a"; +$aw-icon-x: "\ea2b"; +$aw-icon-youtube: "\ea2c"; diff --git a/src/icons/output/aw-icon.css b/src/icons/output/aw-icon.css index 2c29d1ee9..d184b3e37 100644 --- a/src/icons/output/aw-icon.css +++ b/src/icons/output/aw-icon.css @@ -36,26 +36,28 @@ .aw-icon-discord:before { content: "\ea11"; } .aw-icon-divider-vertical:before { content: "\ea12"; } .aw-icon-download:before { content: "\ea13"; } -.aw-icon-github:before { content: "\ea14"; } -.aw-icon-google:before { content: "\ea15"; } -.aw-icon-hamburger-menu:before { content: "\ea16"; } -.aw-icon-light:before { content: "\ea17"; } -.aw-icon-linkedin:before { content: "\ea18"; } -.aw-icon-location:before { content: "\ea19"; } -.aw-icon-logout-left:before { content: "\ea1a"; } -.aw-icon-logout-right:before { content: "\ea1b"; } -.aw-icon-microsoft:before { content: "\ea1c"; } -.aw-icon-minus:before { content: "\ea1d"; } -.aw-icon-nuxt:before { content: "\ea1e"; } -.aw-icon-platform:before { content: "\ea1f"; } -.aw-icon-plus:before { content: "\ea20"; } -.aw-icon-product-hunt:before { content: "\ea21"; } -.aw-icon-refine:before { content: "\ea22"; } -.aw-icon-rest:before { content: "\ea23"; } -.aw-icon-search:before { content: "\ea24"; } -.aw-icon-star:before { content: "\ea25"; } -.aw-icon-system:before { content: "\ea26"; } -.aw-icon-twitter:before { content: "\ea27"; } -.aw-icon-vue:before { content: "\ea28"; } -.aw-icon-x:before { content: "\ea29"; } -.aw-icon-youtube:before { content: "\ea2a"; } +.aw-icon-ext-link:before { content: "\ea14"; } +.aw-icon-github:before { content: "\ea15"; } +.aw-icon-google:before { content: "\ea16"; } +.aw-icon-hamburger-menu:before { content: "\ea17"; } +.aw-icon-light:before { content: "\ea18"; } +.aw-icon-linkedin:before { content: "\ea19"; } +.aw-icon-location:before { content: "\ea1a"; } +.aw-icon-logout-left:before { content: "\ea1b"; } +.aw-icon-logout-right:before { content: "\ea1c"; } +.aw-icon-message:before { content: "\ea1d"; } +.aw-icon-microsoft:before { content: "\ea1e"; } +.aw-icon-minus:before { content: "\ea1f"; } +.aw-icon-nuxt:before { content: "\ea20"; } +.aw-icon-platform:before { content: "\ea21"; } +.aw-icon-plus:before { content: "\ea22"; } +.aw-icon-product-hunt:before { content: "\ea23"; } +.aw-icon-refine:before { content: "\ea24"; } +.aw-icon-rest:before { content: "\ea25"; } +.aw-icon-search:before { content: "\ea26"; } +.aw-icon-star:before { content: "\ea27"; } +.aw-icon-system:before { content: "\ea28"; } +.aw-icon-twitter:before { content: "\ea29"; } +.aw-icon-vue:before { content: "\ea2a"; } +.aw-icon-x:before { content: "\ea2b"; } +.aw-icon-youtube:before { content: "\ea2c"; } diff --git a/src/icons/output/aw-icon.eot b/src/icons/output/aw-icon.eot index c2e4a0dba..a113f9059 100644 Binary files a/src/icons/output/aw-icon.eot and b/src/icons/output/aw-icon.eot differ diff --git a/src/icons/output/aw-icon.scss b/src/icons/output/aw-icon.scss index 830980aa6..11497b5fd 100644 --- a/src/icons/output/aw-icon.scss +++ b/src/icons/output/aw-icon.scss @@ -35,29 +35,31 @@ .aw-icon-discord:before { content: "\ea11"; } .aw-icon-divider-vertical:before { content: "\ea12"; } .aw-icon-download:before { content: "\ea13"; } -.aw-icon-github:before { content: "\ea14"; } -.aw-icon-google:before { content: "\ea15"; } -.aw-icon-hamburger-menu:before { content: "\ea16"; } -.aw-icon-light:before { content: "\ea17"; } -.aw-icon-linkedin:before { content: "\ea18"; } -.aw-icon-location:before { content: "\ea19"; } -.aw-icon-logout-left:before { content: "\ea1a"; } -.aw-icon-logout-right:before { content: "\ea1b"; } -.aw-icon-microsoft:before { content: "\ea1c"; } -.aw-icon-minus:before { content: "\ea1d"; } -.aw-icon-nuxt:before { content: "\ea1e"; } -.aw-icon-platform:before { content: "\ea1f"; } -.aw-icon-plus:before { content: "\ea20"; } -.aw-icon-product-hunt:before { content: "\ea21"; } -.aw-icon-refine:before { content: "\ea22"; } -.aw-icon-rest:before { content: "\ea23"; } -.aw-icon-search:before { content: "\ea24"; } -.aw-icon-star:before { content: "\ea25"; } -.aw-icon-system:before { content: "\ea26"; } -.aw-icon-twitter:before { content: "\ea27"; } -.aw-icon-vue:before { content: "\ea28"; } -.aw-icon-x:before { content: "\ea29"; } -.aw-icon-youtube:before { content: "\ea2a"; } +.aw-icon-ext-link:before { content: "\ea14"; } +.aw-icon-github:before { content: "\ea15"; } +.aw-icon-google:before { content: "\ea16"; } +.aw-icon-hamburger-menu:before { content: "\ea17"; } +.aw-icon-light:before { content: "\ea18"; } +.aw-icon-linkedin:before { content: "\ea19"; } +.aw-icon-location:before { content: "\ea1a"; } +.aw-icon-logout-left:before { content: "\ea1b"; } +.aw-icon-logout-right:before { content: "\ea1c"; } +.aw-icon-message:before { content: "\ea1d"; } +.aw-icon-microsoft:before { content: "\ea1e"; } +.aw-icon-minus:before { content: "\ea1f"; } +.aw-icon-nuxt:before { content: "\ea20"; } +.aw-icon-platform:before { content: "\ea21"; } +.aw-icon-plus:before { content: "\ea22"; } +.aw-icon-product-hunt:before { content: "\ea23"; } +.aw-icon-refine:before { content: "\ea24"; } +.aw-icon-rest:before { content: "\ea25"; } +.aw-icon-search:before { content: "\ea26"; } +.aw-icon-star:before { content: "\ea27"; } +.aw-icon-system:before { content: "\ea28"; } +.aw-icon-twitter:before { content: "\ea29"; } +.aw-icon-vue:before { content: "\ea2a"; } +.aw-icon-x:before { content: "\ea2b"; } +.aw-icon-youtube:before { content: "\ea2c"; } $aw-icon-apple: "\ea01"; $aw-icon-arrow-down: "\ea02"; @@ -78,26 +80,28 @@ $aw-icon-dark: "\ea10"; $aw-icon-discord: "\ea11"; $aw-icon-divider-vertical: "\ea12"; $aw-icon-download: "\ea13"; -$aw-icon-github: "\ea14"; -$aw-icon-google: "\ea15"; -$aw-icon-hamburger-menu: "\ea16"; -$aw-icon-light: "\ea17"; -$aw-icon-linkedin: "\ea18"; -$aw-icon-location: "\ea19"; -$aw-icon-logout-left: "\ea1a"; -$aw-icon-logout-right: "\ea1b"; -$aw-icon-microsoft: "\ea1c"; -$aw-icon-minus: "\ea1d"; -$aw-icon-nuxt: "\ea1e"; -$aw-icon-platform: "\ea1f"; -$aw-icon-plus: "\ea20"; -$aw-icon-product-hunt: "\ea21"; -$aw-icon-refine: "\ea22"; -$aw-icon-rest: "\ea23"; -$aw-icon-search: "\ea24"; -$aw-icon-star: "\ea25"; -$aw-icon-system: "\ea26"; -$aw-icon-twitter: "\ea27"; -$aw-icon-vue: "\ea28"; -$aw-icon-x: "\ea29"; -$aw-icon-youtube: "\ea2a"; +$aw-icon-ext-link: "\ea14"; +$aw-icon-github: "\ea15"; +$aw-icon-google: "\ea16"; +$aw-icon-hamburger-menu: "\ea17"; +$aw-icon-light: "\ea18"; +$aw-icon-linkedin: "\ea19"; +$aw-icon-location: "\ea1a"; +$aw-icon-logout-left: "\ea1b"; +$aw-icon-logout-right: "\ea1c"; +$aw-icon-message: "\ea1d"; +$aw-icon-microsoft: "\ea1e"; +$aw-icon-minus: "\ea1f"; +$aw-icon-nuxt: "\ea20"; +$aw-icon-platform: "\ea21"; +$aw-icon-plus: "\ea22"; +$aw-icon-product-hunt: "\ea23"; +$aw-icon-refine: "\ea24"; +$aw-icon-rest: "\ea25"; +$aw-icon-search: "\ea26"; +$aw-icon-star: "\ea27"; +$aw-icon-system: "\ea28"; +$aw-icon-twitter: "\ea29"; +$aw-icon-vue: "\ea2a"; +$aw-icon-x: "\ea2b"; +$aw-icon-youtube: "\ea2c"; diff --git a/src/icons/output/aw-icon.svg b/src/icons/output/aw-icon.svg index d4bfb5dec..997c81b11 100644 --- a/src/icons/output/aw-icon.svg +++ b/src/icons/output/aw-icon.svg @@ -64,74 +64,80 @@ - + - + + diff --git a/src/icons/output/aw-icon.symbol.svg b/src/icons/output/aw-icon.symbol.svg index 8828199e7..0b02b5a95 100644 --- a/src/icons/output/aw-icon.symbol.svg +++ b/src/icons/output/aw-icon.symbol.svg @@ -1,4 +1,4 @@ - + diff --git a/src/icons/output/aw-icon.ttf b/src/icons/output/aw-icon.ttf index d6fca9a0a..c16ccdc31 100644 Binary files a/src/icons/output/aw-icon.ttf and b/src/icons/output/aw-icon.ttf differ diff --git a/src/icons/output/aw-icon.woff b/src/icons/output/aw-icon.woff index e2308e787..6df627555 100644 Binary files a/src/icons/output/aw-icon.woff and b/src/icons/output/aw-icon.woff differ diff --git a/src/icons/output/aw-icon.woff2 b/src/icons/output/aw-icon.woff2 index 7e93eaea8..f636f0325 100644 Binary files a/src/icons/output/aw-icon.woff2 and b/src/icons/output/aw-icon.woff2 differ diff --git a/src/icons/output/info.json b/src/icons/output/info.json index 45151a031..8b7cfb55b 100644 --- a/src/icons/output/info.json +++ b/src/icons/output/info.json @@ -113,142 +113,154 @@ "className": "aw-icon-download", "unicode": "" }, - "github": { + "ext-link": { "encodedCode": "\\ea14", "prefix": "aw-icon", - "className": "aw-icon-github", + "className": "aw-icon-ext-link", "unicode": "" }, - "google": { + "github": { "encodedCode": "\\ea15", "prefix": "aw-icon", - "className": "aw-icon-google", + "className": "aw-icon-github", "unicode": "" }, - "hamburger-menu": { + "google": { "encodedCode": "\\ea16", "prefix": "aw-icon", - "className": "aw-icon-hamburger-menu", + "className": "aw-icon-google", "unicode": "" }, - "light": { + "hamburger-menu": { "encodedCode": "\\ea17", "prefix": "aw-icon", - "className": "aw-icon-light", + "className": "aw-icon-hamburger-menu", "unicode": "" }, - "linkedin": { + "light": { "encodedCode": "\\ea18", "prefix": "aw-icon", - "className": "aw-icon-linkedin", + "className": "aw-icon-light", "unicode": "" }, - "location": { + "linkedin": { "encodedCode": "\\ea19", "prefix": "aw-icon", - "className": "aw-icon-location", + "className": "aw-icon-linkedin", "unicode": "" }, - "logout-left": { + "location": { "encodedCode": "\\ea1a", "prefix": "aw-icon", - "className": "aw-icon-logout-left", + "className": "aw-icon-location", "unicode": "" }, - "logout-right": { + "logout-left": { "encodedCode": "\\ea1b", "prefix": "aw-icon", - "className": "aw-icon-logout-right", + "className": "aw-icon-logout-left", "unicode": "" }, - "microsoft": { + "logout-right": { "encodedCode": "\\ea1c", "prefix": "aw-icon", - "className": "aw-icon-microsoft", + "className": "aw-icon-logout-right", "unicode": "" }, - "minus": { + "message": { "encodedCode": "\\ea1d", "prefix": "aw-icon", - "className": "aw-icon-minus", + "className": "aw-icon-message", "unicode": "" }, - "nuxt": { + "microsoft": { "encodedCode": "\\ea1e", "prefix": "aw-icon", - "className": "aw-icon-nuxt", + "className": "aw-icon-microsoft", "unicode": "" }, - "platform": { + "minus": { "encodedCode": "\\ea1f", "prefix": "aw-icon", - "className": "aw-icon-platform", + "className": "aw-icon-minus", "unicode": "" }, - "plus": { + "nuxt": { "encodedCode": "\\ea20", "prefix": "aw-icon", - "className": "aw-icon-plus", + "className": "aw-icon-nuxt", "unicode": "" }, - "product-hunt": { + "platform": { "encodedCode": "\\ea21", "prefix": "aw-icon", - "className": "aw-icon-product-hunt", + "className": "aw-icon-platform", "unicode": "" }, - "refine": { + "plus": { "encodedCode": "\\ea22", "prefix": "aw-icon", - "className": "aw-icon-refine", + "className": "aw-icon-plus", "unicode": "" }, - "rest": { + "product-hunt": { "encodedCode": "\\ea23", "prefix": "aw-icon", - "className": "aw-icon-rest", + "className": "aw-icon-product-hunt", "unicode": "" }, - "search": { + "refine": { "encodedCode": "\\ea24", "prefix": "aw-icon", - "className": "aw-icon-search", + "className": "aw-icon-refine", "unicode": "" }, - "star": { + "rest": { "encodedCode": "\\ea25", "prefix": "aw-icon", - "className": "aw-icon-star", + "className": "aw-icon-rest", "unicode": "" }, - "system": { + "search": { "encodedCode": "\\ea26", "prefix": "aw-icon", - "className": "aw-icon-system", + "className": "aw-icon-search", "unicode": "" }, - "twitter": { + "star": { "encodedCode": "\\ea27", "prefix": "aw-icon", - "className": "aw-icon-twitter", + "className": "aw-icon-star", "unicode": "" }, - "vue": { + "system": { "encodedCode": "\\ea28", "prefix": "aw-icon", - "className": "aw-icon-vue", + "className": "aw-icon-system", "unicode": "" }, - "x": { + "twitter": { "encodedCode": "\\ea29", "prefix": "aw-icon", - "className": "aw-icon-x", + "className": "aw-icon-twitter", "unicode": "" }, - "youtube": { + "vue": { "encodedCode": "\\ea2a", "prefix": "aw-icon", - "className": "aw-icon-youtube", + "className": "aw-icon-vue", "unicode": "" + }, + "x": { + "encodedCode": "\\ea2b", + "prefix": "aw-icon", + "className": "aw-icon-x", + "unicode": "" + }, + "youtube": { + "encodedCode": "\\ea2c", + "prefix": "aw-icon", + "className": "aw-icon-youtube", + "unicode": "" } } diff --git a/src/icons/svg/ext-link.svg b/src/icons/svg/ext-link.svg new file mode 100644 index 000000000..5f2901635 --- /dev/null +++ b/src/icons/svg/ext-link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/icons/svg/message.svg b/src/icons/svg/message.svg new file mode 100644 index 000000000..8b72974e2 --- /dev/null +++ b/src/icons/svg/message.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/lib/actions/highlight.ts b/src/lib/actions/highlight.ts new file mode 100644 index 000000000..8055de859 --- /dev/null +++ b/src/lib/actions/highlight.ts @@ -0,0 +1,6 @@ +export const highlight = (node: HTMLElement, text: string[]) => { + text.forEach((word) => { + const regex = new RegExp(`(${word})`, 'gi'); + node.innerHTML = node.innerHTML.replace(regex, '$1'); + }); +}; diff --git a/src/lib/appwrite/index.ts b/src/lib/appwrite/index.ts new file mode 100644 index 000000000..68fc1da79 --- /dev/null +++ b/src/lib/appwrite/index.ts @@ -0,0 +1,9 @@ +import { PUBLIC_APPWRITE_PROJECT_ID } from '$env/static/public'; +import { Client, Databases, Functions } from 'appwrite'; + +export const client = new Client(); + +client.setEndpoint('https://cloud.appwrite.io/v1').setProject(PUBLIC_APPWRITE_PROJECT_ID); + +export const databases = new Databases(client); +export const functions = new Functions(client); diff --git a/src/lib/components/DropdownMenu/DropdownCheckboxItem.svelte b/src/lib/components/DropdownMenu/DropdownCheckboxItem.svelte new file mode 100644 index 000000000..7aa2a4fc7 --- /dev/null +++ b/src/lib/components/DropdownMenu/DropdownCheckboxItem.svelte @@ -0,0 +1,24 @@ + + + diff --git a/src/lib/components/DropdownMenu/DropdownMenu.svelte b/src/lib/components/DropdownMenu/DropdownMenu.svelte new file mode 100644 index 000000000..25de115b5 --- /dev/null +++ b/src/lib/components/DropdownMenu/DropdownMenu.svelte @@ -0,0 +1,33 @@ + + + + + diff --git a/src/lib/components/FooterNav.svelte b/src/lib/components/FooterNav.svelte index c88e455d8..ded699ed8 100644 --- a/src/lib/components/FooterNav.svelte +++ b/src/lib/components/FooterNav.svelte @@ -31,11 +31,12 @@ { label: 'Databases', href: '/docs/products/databases' }, { label: 'Functions', href: '/docs/products/functions' }, { label: 'Storage', href: '/docs/products/storage' }, - { label: 'Realtime', href: '/docs/apis/realtime' } + { label: 'Realtime', href: '/docs/apis/realtime' }, ], Learn: [ { label: 'Docs', href: '/docs' }, { label: 'Community', href: '/community' }, + { label: 'Threads', href: '/threads' }, { label: 'Blog', href: '/blog' }, { label: 'Changelog', href: '/changelog' }, { diff --git a/src/lib/components/MainFooter.svelte b/src/lib/components/MainFooter.svelte index 2b8263c9e..691ae16bc 100644 --- a/src/lib/components/MainFooter.svelte +++ b/src/lib/components/MainFooter.svelte @@ -66,3 +66,9 @@ {/if} + + \ No newline at end of file diff --git a/src/lib/components/SeoOgImage.svelte b/src/lib/components/SeoOgImage.svelte new file mode 100644 index 000000000..773930495 --- /dev/null +++ b/src/lib/components/SeoOgImage.svelte @@ -0,0 +1,13 @@ + + + + + + + diff --git a/src/lib/utils/debounce.ts b/src/lib/utils/debounce.ts new file mode 100644 index 000000000..37bb1586f --- /dev/null +++ b/src/lib/utils/debounce.ts @@ -0,0 +1,14 @@ +export function createDebounce(delay = 500) { + let timeout: NodeJS.Timeout; + return { + debounce: (callback: () => void) => { + clearTimeout(timeout); + timeout = setTimeout(callback, delay); + }, + reset: () => clearTimeout(timeout), + immediate: (callback: () => void) => { + clearTimeout(timeout); + callback(); + } + }; +} diff --git a/src/lib/utils/random.ts b/src/lib/utils/random.ts new file mode 100644 index 000000000..eb61fe938 --- /dev/null +++ b/src/lib/utils/random.ts @@ -0,0 +1,9 @@ +export const deterministicRandom = (options: T[], seed: string): T => { + const index = Math.floor((parseInt(seed, 36) / 36 ** 4) * options.length); + + return options[index]; +}; + +export const random = (min: number, max: number): number => { + return Math.floor(Math.random() * (max - min + 1) + min); +}; diff --git a/src/markdoc/layouts/Article.svelte b/src/markdoc/layouts/Article.svelte index 7094c7e6a..ea34fc456 100644 --- a/src/markdoc/layouts/Article.svelte +++ b/src/markdoc/layouts/Article.svelte @@ -15,9 +15,9 @@ @@ -70,12 +69,7 @@ - - - - - - + diff --git a/src/markdoc/layouts/Category.svelte b/src/markdoc/layouts/Category.svelte index d169e781d..e8883cd29 100644 --- a/src/markdoc/layouts/Category.svelte +++ b/src/markdoc/layouts/Category.svelte @@ -1,89 +1,89 @@ - - {seoTitle} - - - - - - - - - - - - + + {seoTitle} + + + + + + + + + + + +
-
-
-
- - -
-
-

{name}

-

- {description} -

-
- -
+
-
-
    - {#each posts as post} - {@const author = authors.find((a) => a.slug.includes(post.author))} - {#if author} -
    - {/if} - {/each} -
-
-
-
- - -
-
-
-
-
+
    + {#each posts as post} + {@const author = authors.find((a) => a.slug.includes(post.author))} + {#if author} +
    + {/if} + {/each} +
+ +
+
+ + +
+
+ + + diff --git a/src/markdoc/layouts/Post.svelte b/src/markdoc/layouts/Post.svelte index 994e4d758..7382e7ad8 100644 --- a/src/markdoc/layouts/Post.svelte +++ b/src/markdoc/layouts/Post.svelte @@ -66,7 +66,7 @@
+ + diff --git a/src/routes/threads/TagsDropdown.svelte b/src/routes/threads/TagsDropdown.svelte new file mode 100644 index 000000000..44a3f1d9a --- /dev/null +++ b/src/routes/threads/TagsDropdown.svelte @@ -0,0 +1,113 @@ + + + + + + {#if open} + + {/if} + + + diff --git a/src/routes/threads/ThreadCard.svelte b/src/routes/threads/ThreadCard.svelte new file mode 100644 index 000000000..f6972e36f --- /dev/null +++ b/src/routes/threads/ThreadCard.svelte @@ -0,0 +1,68 @@ + + +{#key highlightTerms} + +
+

+ {thread.title} +

+ +
+ +

+ {thread.content.length > 200 ? thread.content.slice(0, 200) + '...' : thread.content} +

+ +
+
    + {#each thread.tags ?? [] as tag} +
  • +
    {tag}
    +
  • + {/each} +
+ +
+
+
+
+{/key} + + diff --git a/src/routes/threads/[id]/+page.server.ts b/src/routes/threads/[id]/+page.server.ts new file mode 100644 index 000000000..1985134c2 --- /dev/null +++ b/src/routes/threads/[id]/+page.server.ts @@ -0,0 +1,22 @@ +import { error } from '@sveltejs/kit'; +import { getRelatedThreads, getThread, getThreadMessages } from '../helpers.js'; + +export const prerender = false; + +export const load = async ({ params }) => { + const id = params.id; + + try { + const thread = await getThread(id); + const related = await getRelatedThreads(thread); + const messages = await getThreadMessages(id); + + return { + ...thread, + related, + messages, + }; + } catch (e) { + throw error(404, 'Thread not found'); + } +}; diff --git a/src/routes/threads/[id]/+page.svelte b/src/routes/threads/[id]/+page.svelte new file mode 100644 index 000000000..97b76d39b --- /dev/null +++ b/src/routes/threads/[id]/+page.svelte @@ -0,0 +1,254 @@ + + + + + {title} + + + + + + + + + +
+
+
+
+ + +

{data.title}

+
    +
  • + + {data.vote_count} +
  • + {#each data.tags ?? [] as tag} +
  • + {tag} +
  • + {/each} +
+
+ +
+ +
+
+ {#each data.messages ?? [] as message, i} + {@const isFirst = i === 0} + + {#if isFirst} +
+ + TL;DR + + {data.tldr} +
+ {/if} +
+ {/each} +
+ Reply +

+ Reply to this thread by joining our Discord +

+ + + Reply on Discord + +
+
+ +
+
+ + +
+ + +
+
+ + diff --git a/src/routes/threads/[id]/CodeRenderer.svelte b/src/routes/threads/[id]/CodeRenderer.svelte new file mode 100644 index 000000000..065285daf --- /dev/null +++ b/src/routes/threads/[id]/CodeRenderer.svelte @@ -0,0 +1,120 @@ + + +{#if insideMultiCode} + {#if $selected === language} + + {@html result} + {/if} +{:else} +
+
+
+ {#if platformMap[language]} +
+
{platformMap[language]}
+
+ {/if} +
+
+
    +
  • + + + + {copyText} + + +
  • +
+
+
+
+ + {@html result} +
+
+{/if} + + diff --git a/src/routes/threads/[id]/LinkRenderer.svelte b/src/routes/threads/[id]/LinkRenderer.svelte new file mode 100644 index 000000000..db46f1e43 --- /dev/null +++ b/src/routes/threads/[id]/LinkRenderer.svelte @@ -0,0 +1,11 @@ + + +{text} diff --git a/src/routes/threads/[id]/MessageCard.svelte b/src/routes/threads/[id]/MessageCard.svelte new file mode 100644 index 000000000..75b5a190a --- /dev/null +++ b/src/routes/threads/[id]/MessageCard.svelte @@ -0,0 +1,87 @@ + + +
+
+
+
+ +
+ {message.author} +
+ + {formatTimestamp(message.timestamp)} + +
+
+ +
+ +
+ + diff --git a/src/routes/threads/helpers.ts b/src/routes/threads/helpers.ts new file mode 100644 index 000000000..079c49418 --- /dev/null +++ b/src/routes/threads/helpers.ts @@ -0,0 +1,115 @@ +import { + PUBLIC_APPWRITE_COL_MESSAGES_ID, + PUBLIC_APPWRITE_COL_THREADS_ID, + PUBLIC_APPWRITE_DB_MAIN_ID, + PUBLIC_APPWRITE_FN_TLDR_ID +} from '$env/static/public'; +import { databases, functions } from '$lib/appwrite'; +import { Query } from 'appwrite'; +import type { DiscordMessage, DiscordThread } from './types'; + +type Ranked = { + data: T; + rank: number; // Percentage of query words found, from 0 to 1 +}; + +type FilterThreadsArgs = { + threads: DiscordThread[]; + q?: string | null; + tags?: string[]; + allTags?: boolean; +}; + +export function filterThreads({ q, threads: threadDocs, tags, allTags }: FilterThreadsArgs) { + const threads = tags + ? threadDocs.filter((thread) => { + const lowercaseTags = thread.tags?.map((tag) => tag.toLowerCase()); + if (allTags) { + return tags?.every((tag) => lowercaseTags?.includes(tag.toLowerCase())); + } else { + return tags?.some((tag) => lowercaseTags?.includes(tag.toLowerCase())); + } + }) + : threadDocs; + + if (!q) return threads; + + const queryWords = q.toLowerCase().split(/\s+/); + const rankPerWord = 1 / queryWords.length; + const res: Ranked[] = []; + + threads.forEach((item) => { + const foundWords = new Set(); + + Object.values(item).forEach((value) => { + const stringified = JSON.stringify(value).toLowerCase(); + + queryWords.forEach((word) => { + if (stringified.includes(word)) { + foundWords.add(word); + } + }); + }); + + const rank = foundWords.size * rankPerWord; + + if (rank > 0) { + res.push({ + data: item, + rank + }); + } + }); + + return res.sort((a, b) => b.rank - a.rank).map(({ data }) => data); +} + +type GetThreadsArgs = Omit; + +export async function getThreads({ q, tags, allTags }: GetThreadsArgs) { + let query = [ + q ? Query.search('search_meta', q) : undefined + ]; + + tags = tags?.filter(Boolean).map((tag) => tag.toLowerCase()) ?? []; + + if (tags.length > 0) { + query = [...query, Query.search('tags', tags.join(','))]; + } + + const data = await databases.listDocuments( + PUBLIC_APPWRITE_DB_MAIN_ID, + PUBLIC_APPWRITE_COL_THREADS_ID, + query.filter(Boolean) as string[] + ); + + const threadDocs = data.documents as unknown as DiscordThread[]; + return filterThreads({ threads: threadDocs, q, tags, allTags }); +} + +export async function getThread($id: string) { + return (await databases.getDocument( + PUBLIC_APPWRITE_DB_MAIN_ID, + PUBLIC_APPWRITE_COL_THREADS_ID, + $id + )) as unknown as DiscordThread; +} + +export async function getRelatedThreads(thread: DiscordThread, limit: number = 3) { + const tags = thread.tags?.filter(Boolean) ?? []; + const relatedThreads = await getThreads({ q: null, tags, allTags: false }); + + return relatedThreads.filter(({ $id }) => $id !== thread.$id).slice(0, limit); +} + +export async function getThreadMessages(threadId: string) { + const data = await databases.listDocuments( + PUBLIC_APPWRITE_DB_MAIN_ID, + PUBLIC_APPWRITE_COL_MESSAGES_ID, + [Query.equal('threadId', threadId)].filter(Boolean) as string[] + ); + + return (data.documents as unknown as DiscordMessage[]).sort( + (a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime() + ); +} \ No newline at end of file diff --git a/src/routes/threads/types.ts b/src/routes/threads/types.ts new file mode 100644 index 000000000..98e9d6257 --- /dev/null +++ b/src/routes/threads/types.ts @@ -0,0 +1,38 @@ +import type { Models } from 'appwrite'; + +export type MockThread = { + id: string; + username?: string; + title: string; + text: string; + replies: MockMessage[]; +}; + +export interface DiscordMessage extends Pick { + threadId: string; + author: string; + author_avatar: string; + message: string; + role?: string; + /* `UTC` timestamp */ + timestamp: string; +} + +export interface DiscordThread extends Pick { + discord_id: string; + author: string; + tags?: string[]; + author_avatar: string; + seo_description?: string; + content: string; + title: string; + search_meta?: string; + tldr: string; + vote_count: number; + message_count: number; +} + +export type MockMessage = { + username?: string; + text: string; +}; diff --git a/src/scss/6-elements/_btn-tag.scss b/src/scss/6-elements/_btn-tag.scss new file mode 100644 index 000000000..0c6787c9a --- /dev/null +++ b/src/scss/6-elements/_btn-tag.scss @@ -0,0 +1,38 @@ +@use '../abstract' as *; + +.#{$p}-btn-tag { + --p-tag-text-color: var(--aw-color-primary); + --p-tag-bg-color: var(--aw-color-greyscale-100); + --p-tag-border-color: var(--p-tag-bg-color); + + + color: hsl(var(--p-tag-text-color)); + background-color: hsl(var(--p-tag-bg-color)); + border: 1px solid hsl(var(--p-tag-border-color)); + + padding-block: pxToRem(4); + padding-inline: pxToRem(8); + border-radius: pxToRem(12); + font-size: var(--aw-font-size-micro); + line-height: var(--aw-line-height-tiny); + + #{$theme-dark} & { + --p-tag-bg-color: var(--aw-color-greyscale-750); + + &:where(:hover) { + --p-tag-bg-color: var(--aw-color-greyscale-700); + } + + &:where(:active) { + --p-tag-bg-color: var(--aw-color-greyscale-800); + } + + &:where(.is-selected) { + --p-tag-border-color: var(--aw-color-white); + } + + &:where(:disabled) { + --p-tag-bg-color: var(--aw-color-greyscale-800); + } + } +} \ No newline at end of file diff --git a/src/scss/6-elements/_container.scss b/src/scss/6-elements/_container.scss index fb3d136d9..691f2fd30 100644 --- a/src/scss/6-elements/_container.scss +++ b/src/scss/6-elements/_container.scss @@ -9,6 +9,7 @@ @media #{$break1} { padding-inline: pxToRem(20); } } + .#{$p}-main-section { > * { padding-block:pxToRem(24); } >:first-child { padding-block-start:0; } diff --git a/src/scss/6-elements/_icon-button.scss b/src/scss/6-elements/_icon-button.scss index 1df9e90f2..7fab354b8 100644 --- a/src/scss/6-elements/_icon-button.scss +++ b/src/scss/6-elements/_icon-button.scss @@ -1,7 +1,8 @@ @use '../abstract' as *; .#{$p}-icon-button { - display: block; + display: flex; + gap: pxToRem(4); position: relative; block-size:pxToRem(28); inline-size:pxToRem(28); @@ -10,10 +11,17 @@ border-radius: pxToRem(8); > [class*='icon'] { - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); + position: relative; + &::before { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + &.is-more-content { + inline-size:fit-content; padding:pxToRem(4); line-height:pxToRem(18); + > [class*='icon'] { inline-size:pxToRem(16); } } diff --git a/src/scss/6-elements/_index.scss b/src/scss/6-elements/_index.scss index 12dc5ecf0..f5be36d82 100644 --- a/src/scss/6-elements/_index.scss +++ b/src/scss/6-elements/_index.scss @@ -12,6 +12,7 @@ @forward "badges"; @forward "numeric-badge"; @forward "tag"; +@forward "btn-tag"; @forward "inline-tag"; @forward "card"; @forward "lists"; diff --git a/src/scss/6-elements/_link.scss b/src/scss/6-elements/_link.scss index e2c3d5b90..1148fe3a2 100644 --- a/src/scss/6-elements/_link.scss +++ b/src/scss/6-elements/_link.scss @@ -31,5 +31,9 @@ &.is-inline { text-decoration: underline; } + + &.is-secondary { + --p-link-color-text-default: var(--aw-color-secondary); + } } diff --git a/src/scss/_10-utilities.scss b/src/scss/_10-utilities.scss index 07a746a55..74d47857c 100644 --- a/src/scss/_10-utilities.scss +++ b/src/scss/_10-utilities.scss @@ -47,6 +47,7 @@ .#{$p}-u-margin-inline-32-negative { margin-inline:pxToRem(-32); } .#{$p}-u-margin-block-0 { margin-block:0; } +.#{$p}-u-margin-block-80 { margin-block:pxToRem(80); } .#{$p}-u-margin-block-start-40 { margin-block-start:pxToRem(40); } .#{$p}-u-margin-block-start-40-mobile { @media #{$break1} {margin-block-start:pxToRem(40);} } diff --git a/svelte.config.js b/svelte.config.js index 8316dd0e4..472fd466a 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -59,4 +59,4 @@ const config = { } } }; -export default config; +export default config; \ No newline at end of file diff --git a/teams-labels.png b/teams-labels.png deleted file mode 100644 index 6dfc07152..000000000 Binary files a/teams-labels.png and /dev/null differ