diff --git a/package.json b/package.json index 7e86429210..423f91860c 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "lint": "prettier --plugin-search-dir . --check . && eslint .", "format": "prettier --plugin-search-dir . --write .", + "clean": "rm -rf node_modules && rm -rf .svelte_kit && pnpm i", "test:integration": "playwright test", "test:unit": "vitest", "icons:build": "node ./src/icons/build.js", diff --git a/src/app.d.ts b/src/app.d.ts index f59b884c51..7b32cc9ae1 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,12 +1,14 @@ // See https://kit.svelte.dev/docs/types#app // for information about these interfaces declare global { - namespace App { - // interface Error {} - // interface Locals {} - // interface PageData {} - // interface Platform {} - } + namespace App { + // interface Error {} + // interface Locals {} + interface PageData { + changelogEntries: number; + } + // interface Platform {} + } } export {}; diff --git a/src/lib/animations/scroll-indicator.svelte b/src/lib/animations/scroll-indicator.svelte index 9769f7b060..71c1030978 100644 --- a/src/lib/animations/scroll-indicator.svelte +++ b/src/lib/animations/scroll-indicator.svelte @@ -1,82 +1,58 @@
-
+
diff --git a/src/lib/components/Article.svelte b/src/lib/components/Article.svelte index 7b59e0bb52..94d662879c 100644 --- a/src/lib/components/Article.svelte +++ b/src/lib/components/Article.svelte @@ -1,4 +1,6 @@ + + + + + diff --git a/src/markdoc/nodes/Item.svelte b/src/markdoc/nodes/Item.svelte index af93946a23..7d32536f9c 100644 --- a/src/markdoc/nodes/Item.svelte +++ b/src/markdoc/nodes/Item.svelte @@ -1,7 +1,9 @@ -
  • +
  • diff --git a/src/markdoc/nodes/Link.svelte b/src/markdoc/nodes/Link.svelte index 881f4b02fb..8f9f183613 100644 --- a/src/markdoc/nodes/Link.svelte +++ b/src/markdoc/nodes/Link.svelte @@ -1,4 +1,5 @@ \ No newline at end of file +> + + diff --git a/src/markdoc/nodes/List.svelte b/src/markdoc/nodes/List.svelte index ac322bcc40..cbb77befa1 100644 --- a/src/markdoc/nodes/List.svelte +++ b/src/markdoc/nodes/List.svelte @@ -1,4 +1,5 @@ diff --git a/src/markdoc/nodes/Paragraph.svelte b/src/markdoc/nodes/Paragraph.svelte index ec9913fec0..1b66c8fc3d 100644 --- a/src/markdoc/nodes/Paragraph.svelte +++ b/src/markdoc/nodes/Paragraph.svelte @@ -1,10 +1,12 @@ - diff --git a/src/routes/+layout.server.ts b/src/routes/+layout.server.ts index 189f71e2e1..a8038489f9 100644 --- a/src/routes/+layout.server.ts +++ b/src/routes/+layout.server.ts @@ -1 +1,11 @@ +import { getAllChangelogEntries } from "./changelog/utils"; + export const prerender = true; + + +export const load = async () => { + return { + changelogEntries: (await getAllChangelogEntries()).length + } + +}; \ No newline at end of file diff --git a/src/routes/changelog/(entries)/2023-08-30.markdoc b/src/routes/changelog/(entries)/2023-08-30.markdoc new file mode 100644 index 0000000000..c9bab01615 --- /dev/null +++ b/src/routes/changelog/(entries)/2023-08-30.markdoc @@ -0,0 +1,18 @@ +--- +layout: changelog +title: Appwrite 1.4 +date: 2023-08-30 +cover: /images/changelog/2023-08-30.png +--- + +We’ve just released Appwrite 1.4 with the goals to eliminate barriers to get started, maximize flexibility to grow, and deliver improved security for peace of mind. + +Notable new features: +- Next generation of Appwrite Functions brings Git deployments, http executions, intuitive syntax, and reliable logging. +- Command center for quicker console navigation and keyboard shortcuts +- AI assistant to help you search docs and answer questions. +- One-Click migrations lets you migrate from Firebase, Supabase, and NHost. You can also migrate between Appwrite Cloud and self-hosted. + +{% arrow_link href="https://dev.to/appwrite/appwrite-14-brings-command-center-ai-one-click-migrations-and-upgraded-functions-1ch2" %} +Read the full announcement +{% /arrow_link %} diff --git a/src/routes/changelog/(entries)/2023-09-21.markdoc b/src/routes/changelog/(entries)/2023-09-21.markdoc new file mode 100644 index 0000000000..c04f1805aa --- /dev/null +++ b/src/routes/changelog/(entries)/2023-09-21.markdoc @@ -0,0 +1,16 @@ +--- +layout: changelog +title: Meet the new Appwrite +date: 2023-09-21 +cover: /images/changelog/2023-09-21.png +--- + +Unveiling Appwrite's new fresh look and feel with a new brand, website and experience. + +- New brand, new logo, and new design that aligns with our growth +- Design elements inspired by the community and reflects our values +- New documentation with improved navigation, search, and more beginner friendly tutorials + +{% arrow_link href="/changelog/2023-12-20" %} +Read the full announcement +{% /arrow_link %} diff --git a/src/routes/changelog/(entries)/2023-12-20.markdoc b/src/routes/changelog/(entries)/2023-12-20.markdoc new file mode 100644 index 0000000000..f5f835bab6 --- /dev/null +++ b/src/routes/changelog/(entries)/2023-12-20.markdoc @@ -0,0 +1,19 @@ +--- +layout: changelog +title: Announcing Appwrite Pro +date: 2023-12-20 +cover: /images/changelog/2023-12-20.png +--- + +Appwrite Pro is now available for Appwrite Cloud developers. + +Previously, all Appwrite Cloud developers used the Starter plan with unrestricted resources. +With Pro, you can choose between two different plans for your organization(s): + +- Starter: a free plan that provides an easy starting point for budding projects +- Pro: for developers who need more resources to scale their apps, +customized branding in emails and messages, more team members per organization, and premium support. + +{% arrow_link href="/blog/announcing-appwrite-pro" %} +Read the full announcement +{% /arrow_link %} diff --git a/src/routes/changelog/(entries)/2023-12-23.markdoc b/src/routes/changelog/(entries)/2023-12-23.markdoc new file mode 100644 index 0000000000..ed16b0c043 --- /dev/null +++ b/src/routes/changelog/(entries)/2023-12-23.markdoc @@ -0,0 +1,11 @@ +--- +layout: changelog +title: Changelog +date: 2023-12-23 +cover: /images/changelog/2023-12-23.png +--- + +Appwrite's capabilities grow everyday and it's difficult to keep up. +To help everyone stay updated, we added a dedicated changelog page to the Appwrite website. + +You can now find all of Appwrite's latest features, changes, and announcements all in one place. \ No newline at end of file diff --git a/src/routes/changelog/ChangelogEntry.svelte b/src/routes/changelog/ChangelogEntry.svelte new file mode 100644 index 0000000000..b07337f75f --- /dev/null +++ b/src/routes/changelog/ChangelogEntry.svelte @@ -0,0 +1,46 @@ + + +
    + + {#if entry.cover} + + + + {/if} + + +
    + + diff --git a/src/routes/changelog/[[page]]/+page.svelte b/src/routes/changelog/[[page]]/+page.svelte new file mode 100644 index 0000000000..4adf46cd0a --- /dev/null +++ b/src/routes/changelog/[[page]]/+page.svelte @@ -0,0 +1,140 @@ + + + + + {seo.title} + + + + + + + + + + + + + + +
    +
    +

    Changelog

    +
      + {#each data.entries as entry} +
    • +
      + + + +
    • + {/each} +
    + + {#if data.nextPage} + + {/if} +
    +
    +
    + + + +
    +
    +
    + + diff --git a/src/routes/changelog/[[page]]/+page.ts b/src/routes/changelog/[[page]]/+page.ts new file mode 100644 index 0000000000..30dddd4935 --- /dev/null +++ b/src/routes/changelog/[[page]]/+page.ts @@ -0,0 +1,25 @@ +import { CHANGELOG_DEPENDENCY, getAllChangelogEntries } from '../utils'; + +const PER_PAGE = 5; + +export const entries = async () => { + const entries = await getAllChangelogEntries(); + const totalPages = Math.ceil(entries.length / PER_PAGE); + return Array.from({ length: totalPages }, (_, i) => { + return { + page: (i + 1).toString() + }; + }); +}; + +export const load = async ({ depends, params }) => { + depends(CHANGELOG_DEPENDENCY); + + const page = parseInt(params.page || '1', 10); + const entries = await getAllChangelogEntries(); + + return { + entries: entries.slice(0, page * PER_PAGE), + nextPage: page < Math.ceil(entries.length / PER_PAGE) ? page + 1 : null + }; +}; diff --git a/src/routes/changelog/entry/[entry]/+page.svelte b/src/routes/changelog/entry/[entry]/+page.svelte new file mode 100644 index 0000000000..07b4feed40 --- /dev/null +++ b/src/routes/changelog/entry/[entry]/+page.svelte @@ -0,0 +1,87 @@ + + + + + {seo.title + CHANGELOG_TITLE_SUFFIX} + + + + + + + + + + + + + + + +
    +
    + +
    + +
    +
    + + + +
    +
    +
    + + diff --git a/src/routes/changelog/entry/[entry]/+page.ts b/src/routes/changelog/entry/[entry]/+page.ts new file mode 100644 index 0000000000..3f348c40bb --- /dev/null +++ b/src/routes/changelog/entry/[entry]/+page.ts @@ -0,0 +1,28 @@ +import { error } from '@sveltejs/kit'; +import { getAllChangelogEntries } from '../../utils.js'; +import type { EntryGenerator } from './$types.js'; + +export const entries: EntryGenerator = async () => { + const entries = await getAllChangelogEntries(); + return entries.map((entry) => { + return { + entry: entry.slug + } + }); +} + +export const load = async ({ params, }) => { + const entries = await getAllChangelogEntries(); + const entry = entries.find((entry) => { + return entry.filepath.includes(params.entry); + }); + + if (!entry) { + throw error(404, 'Not found') + } + + return { + ...entry + } + +}; \ No newline at end of file diff --git a/src/routes/changelog/utils.ts b/src/routes/changelog/utils.ts new file mode 100644 index 0000000000..b313f22e79 --- /dev/null +++ b/src/routes/changelog/utils.ts @@ -0,0 +1,44 @@ +import { browser } from '$app/environment'; +import { page } from '$app/stores'; +import { isNumeric } from '$lib/utils/is'; +import type { ChangelogData } from '$markdoc/layouts/Changelog.svelte'; +import { get } from 'svelte/store'; + +type ChangelogComponent = { + frontmatter: ChangelogData; + default: ConstructorOfATypedSvelteComponent; +}; + +export const getAllChangelogEntries = async () => { + const entriesGlob = await import.meta.glob('./**/*.markdoc', { eager: true }); + let entries = Object.entries(entriesGlob).map(([filepath, component]) => { + const typedComponent = component as ChangelogComponent; + const { frontmatter } = typedComponent; + const slug = filepath.replace(/\.markdoc$/, '').replace('(entries)/', ''); + const href = `/changelog/entry/${slug}`; + + return { ...frontmatter, component: typedComponent.default, filepath, href, slug }; + }); + entries = entries.filter(({ filepath }) => { + return filepath.includes('(entries)'); + }); + + return entries.sort((a, b) => { + const aDate = new Date(a.date); + const bDate = new Date(b.date); + return bDate.getTime() - aDate.getTime(); + }); +}; + +export const CHANGELOG_DEPENDENCY = 'changelog'; + +export const CHANGELOG_KEY = 'changelog'; + +export function hasNewChangelog() { + if (!browser) return false; + + const prev = localStorage.getItem(CHANGELOG_KEY); + if (!prev) return true; + + return isNumeric(prev) && JSON.parse(prev) < get(page).data.changelogEntries; +} diff --git a/src/routes/titles.ts b/src/routes/titles.ts index 66920f6ba9..71b4af2a05 100644 --- a/src/routes/titles.ts +++ b/src/routes/titles.ts @@ -2,3 +2,4 @@ export const TITLE_SUFFIX = ' - Appwrite'; export const DOCS_TITLE_SUFFIX = ' - Docs' + TITLE_SUFFIX; export const API_REFERENCE_TITLE_SUFFIX = ' API Reference' + DOCS_TITLE_SUFFIX; export const BLOG_TITLE_SUFFIX = ' - Blog' + TITLE_SUFFIX; +export const CHANGELOG_TITLE_SUFFIX = ' - Changelog' + TITLE_SUFFIX; diff --git a/src/scss/6-elements/_dot.scss b/src/scss/6-elements/_dot.scss new file mode 100644 index 0000000000..2ac355ddff --- /dev/null +++ b/src/scss/6-elements/_dot.scss @@ -0,0 +1,29 @@ +@use '../abstract' as *; + + +.#{$p}-dot { + border-radius: 16px; + border: 0.5px solid rgba(255, 255, 255, 0.16); + background: linear-gradient( + 138deg, + rgba(255, 255, 255, 0.13) 9.61%, + rgba(255, 255, 255, 0) 105.41% + ); + backdrop-filter: blur(100px); + + width: 16px; + height: 16px; + + + &::after { + content: ''; + background-color: white; + border-radius: 100%; + width: 4px; + height: 4px; + position: absolute; + left: 50%; + top: 50%; + translate: -50% -50%; + } +} \ No newline at end of file diff --git a/src/scss/6-elements/_index.scss b/src/scss/6-elements/_index.scss index 5dc3af6054..12dc5ecf03 100644 --- a/src/scss/6-elements/_index.scss +++ b/src/scss/6-elements/_index.scss @@ -1,5 +1,6 @@ @forward "text-tokens"; /* folder */ +@forward "dot"; @forward "container"; @forward "white-section"; @forward "link"; diff --git a/src/scss/8-sequences/_main-article.scss b/src/scss/8-sequences/_main-article.scss index 33a9606e8d..fdc85a67ee 100644 --- a/src/scss/8-sequences/_main-article.scss +++ b/src/scss/8-sequences/_main-article.scss @@ -4,13 +4,14 @@ &-header { position:relative; display:flex; flex-direction:column; gap:pxToRem(8); - margin-block-end:pxToRem(48); + margin-block-end:pxToRem(32); @media #{$break2open} { padding-block-end:pxToRem(32); border-block-end:solid pxToRem(1) hsl(var(--aw-color-border)); } @media #{$break3open} { .#{$p}-link { - position:absolute; inset-inline-end:calc(100% + #{pxToRem(74)}); + position:absolute; + inset-inline-end:calc(100% + #{pxToRem(74)}); white-space:nowrap; } } diff --git a/static/images/changelog/2023-08-30.png b/static/images/changelog/2023-08-30.png new file mode 100644 index 0000000000..28b219e56c Binary files /dev/null and b/static/images/changelog/2023-08-30.png differ diff --git a/static/images/changelog/2023-09-21.png b/static/images/changelog/2023-09-21.png new file mode 100644 index 0000000000..ecc5710e43 Binary files /dev/null and b/static/images/changelog/2023-09-21.png differ diff --git a/static/images/changelog/2023-12-20.png b/static/images/changelog/2023-12-20.png new file mode 100644 index 0000000000..9c9aeff1eb Binary files /dev/null and b/static/images/changelog/2023-12-20.png differ diff --git a/static/images/changelog/2023-12-23.png b/static/images/changelog/2023-12-23.png new file mode 100644 index 0000000000..c562024d93 Binary files /dev/null and b/static/images/changelog/2023-12-23.png differ diff --git a/svelte.config.js b/svelte.config.js index cd1059b4a0..8316dd0e45 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -7,7 +7,7 @@ import sequence from 'svelte-sequential-preprocessor'; import staticAdapter from '@sveltejs/adapter-static'; import nodeAdapter from '@sveltejs/adapter-node'; -function absoulute(path) { +function absolute(path) { return join(dirname(fileURLToPath(import.meta.url)), path); } @@ -23,17 +23,18 @@ const config = { vitePreprocess(), markdoc({ generateSchema: true, - nodes: absoulute('./src/markdoc/nodes/_Module.svelte'), - tags: absoulute('./src/markdoc/tags/_Module.svelte'), - partials: absoulute('./src/partials'), + nodes: absolute('./src/markdoc/nodes/_Module.svelte'), + tags: absolute('./src/markdoc/tags/_Module.svelte'), + partials: absolute('./src/partials'), layouts: { - default: absoulute('./src/markdoc/layouts/Article.svelte'), - article: absoulute('./src/markdoc/layouts/Article.svelte'), - tutorial: absoulute('./src/markdoc/layouts/Tutorial.svelte'), - post: absoulute('./src/markdoc/layouts/Post.svelte'), - author: absoulute('./src/markdoc/layouts/Author.svelte'), - category: absoulute('./src/markdoc/layouts/Category.svelte'), - policy: absoulute('./src/markdoc/layouts/Policy.svelte') + default: absolute('./src/markdoc/layouts/Article.svelte'), + article: absolute('./src/markdoc/layouts/Article.svelte'), + tutorial: absolute('./src/markdoc/layouts/Tutorial.svelte'), + post: absolute('./src/markdoc/layouts/Post.svelte'), + author: absolute('./src/markdoc/layouts/Author.svelte'), + category: absolute('./src/markdoc/layouts/Category.svelte'), + policy: absolute('./src/markdoc/layouts/Policy.svelte'), + changelog: absolute('./src/markdoc/layouts/Changelog.svelte') } }), preprocessMeltUI() @@ -52,6 +53,9 @@ const config = { $icons: './src/icons', $appwrite: './node_modules/@appwrite.io/repo', $markdoc: './src/markdoc' + }, + prerender: { + handleHttpError: 'warn' } } };