chore: init
commit
8424b7b98b
|
@ -0,0 +1,6 @@
|
||||||
|
node_modules
|
||||||
|
*.log
|
||||||
|
dist
|
||||||
|
.output
|
||||||
|
.nuxt
|
||||||
|
.env
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"installDependencies": true,
|
||||||
|
"startCommand": "npm run dev"
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"antfu.iconify",
|
||||||
|
"antfu.unocss",
|
||||||
|
"antfu.goto-alias",
|
||||||
|
"csstools.postcss",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"vue.volar"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
{
|
||||||
|
"prettier.enable": false,
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.fixAll.eslint": true
|
||||||
|
},
|
||||||
|
"files.associations": {
|
||||||
|
"*.css": "postcss"
|
||||||
|
},
|
||||||
|
"editor.formatOnSave": false
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://user-images.githubusercontent.com/11247099/140462375-7b7ac4db-35b7-453c-8a05-13d8d20282c4.png" width="600"/>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 align="center">
|
||||||
|
<a href="https://github.com/antfu/vitesse">Vitesse</a> for Nuxt 3
|
||||||
|
</h2><br>
|
||||||
|
|
||||||
|
<pre align="center">
|
||||||
|
🧪 Working in Progress
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<br>
|
||||||
|
<a href="https://vitesse-nuxt3.netlify.app/">🖥 Online Preview</a>
|
||||||
|
<br><br>
|
||||||
|
<a href="https://stackblitz.com/github/antfu/vitesse-nuxt3"><img src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" alt=""></a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- [💚 Nuxt 3](https://v3.nuxtjs.org) - SSR, ESR, File-based routing, components auto importing, modules, etc.
|
||||||
|
|
||||||
|
- ⚡️ Vite - Instant HMR
|
||||||
|
|
||||||
|
- 🎨 [UnoCSS](https://github.com/antfu/unocss) - The instant on-demand atomic CSS engine.
|
||||||
|
|
||||||
|
- 😃 Use icons from any icon sets in Pure CSS, powered by [UnoCSS](https://github.com/antfu/unocss)
|
||||||
|
|
||||||
|
- 🔥 The `<script setup>` syntax
|
||||||
|
|
||||||
|
- 🍍 [State Management via Pinia](https://pinia.esm.dev), see [./composables/user.ts](./composables/user.ts)
|
||||||
|
|
||||||
|
- 📑 [Layout system](./layouts)
|
||||||
|
|
||||||
|
- 📥 APIs auto importing - for Composition API, VueUse and custom composables.
|
||||||
|
|
||||||
|
- 🏎 Zero-config cloud functions and deploy
|
||||||
|
|
||||||
|
- 🦾 TypeScript, of course
|
||||||
|
|
||||||
|
## Plugins
|
||||||
|
|
||||||
|
### Nuxt Modules
|
||||||
|
|
||||||
|
- [VueUse](https://github.com/vueuse/vueuse) - collection of useful composition APIs.
|
||||||
|
- [ColorMode](https://github.com/nuxt-community/color-mode-module) - dark and Light mode with auto detection made easy with Nuxt.
|
||||||
|
- [UnoCSS](https://github.com/antfu/unocss) - the instant on-demand atomic CSS engine.
|
||||||
|
- [Pinia](https://pinia.esm.dev/) - intuitive, type safe, light and flexible Store for Vue.
|
||||||
|
|
||||||
|
## IDE
|
||||||
|
|
||||||
|
We recommend using [VS Code](https://code.visualstudio.com/) with [Volar](https://github.com/johnsoncodehk/volar) to get the best experience (You might want to disable Vetur if you have it).
|
||||||
|
|
||||||
|
## Variations
|
||||||
|
|
||||||
|
- [vitesse](https://github.com/antfu/vitesse) - Opinionated Vite Starter Template
|
||||||
|
- [vitesse-lite](https://github.com/antfu/vitesse-lite) - Lightweight version of Vitesse
|
||||||
|
- [vitesse-nuxt-bridge](https://github.com/antfu/vitesse-nuxt-bridge) - Vitesse for Nuxt 2 with Bridge
|
||||||
|
- [vitesse-webext](https://github.com/antfu/vitesse-webext) - WebExtension Vite starter template
|
||||||
|
|
||||||
|
## Try it now!
|
||||||
|
|
||||||
|
### Online
|
||||||
|
|
||||||
|
<a href="https://stackblitz.com/github/antfu/vitesse-nuxt3"><img src="https://developer.stackblitz.com/img/open_in_stackblitz.svg" alt=""></a>
|
||||||
|
|
||||||
|
### GitHub Template
|
||||||
|
|
||||||
|
[Create a repo from this template on GitHub](https://github.com/antfu/vitesse-nuxt3/generate).
|
||||||
|
|
||||||
|
### Clone to local
|
||||||
|
|
||||||
|
If you prefer to do it manually with the cleaner git history
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx degit antfu/vitesse-nuxt3 my-nuxt3-app
|
||||||
|
cd my-nuxt3-app
|
||||||
|
pnpm i # If you don't have pnpm installed, run: npm install -g pnpm
|
||||||
|
```
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Headers, createFetch, fetch } from 'ohmyfetch'
|
||||||
|
import type { Post } from './types'
|
||||||
|
|
||||||
|
export interface MastodonClientOptions {
|
||||||
|
host: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export class Client {
|
||||||
|
$fetch: ReturnType<typeof createFetch> = undefined!
|
||||||
|
|
||||||
|
constructor(public options: MastodonClientOptions) {
|
||||||
|
this.$fetch = createFetch({
|
||||||
|
defaults: {
|
||||||
|
baseURL: options.host,
|
||||||
|
},
|
||||||
|
fetch,
|
||||||
|
Headers,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getPublicTimeline(): Promise<Post[]> {
|
||||||
|
return this.$fetch('/api/v1/timelines/public')
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
export interface Post {
|
||||||
|
id: string
|
||||||
|
created_at: Date
|
||||||
|
in_reply_to_id: null | string
|
||||||
|
in_reply_to_account_id: null | string
|
||||||
|
sensitive: boolean
|
||||||
|
spoiler_text: string
|
||||||
|
visibility: Visibility
|
||||||
|
language: string
|
||||||
|
uri: string
|
||||||
|
url: string
|
||||||
|
replies_count: number
|
||||||
|
reblogs_count: number
|
||||||
|
favourites_count: number
|
||||||
|
edited_at: null
|
||||||
|
favourited: boolean
|
||||||
|
reblogged: boolean
|
||||||
|
muted: boolean
|
||||||
|
bookmarked: boolean
|
||||||
|
content: string
|
||||||
|
filtered: any[]
|
||||||
|
reblog: null
|
||||||
|
account: Account
|
||||||
|
media_attachments: MediaAttachment[]
|
||||||
|
mentions: any[]
|
||||||
|
tags: Tag[]
|
||||||
|
emojis: Emoji[]
|
||||||
|
card: null
|
||||||
|
poll: null
|
||||||
|
application?: Application
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Account {
|
||||||
|
id: string
|
||||||
|
username: string
|
||||||
|
acct: string
|
||||||
|
display_name: string
|
||||||
|
locked: boolean
|
||||||
|
bot: boolean
|
||||||
|
discoverable: boolean
|
||||||
|
group: boolean
|
||||||
|
created_at: Date
|
||||||
|
note: string
|
||||||
|
url: string
|
||||||
|
avatar: string
|
||||||
|
avatar_static: string
|
||||||
|
header: string
|
||||||
|
header_static: string
|
||||||
|
followers_count: number
|
||||||
|
following_count: number
|
||||||
|
statuses_count: number
|
||||||
|
last_status_at: Date
|
||||||
|
emojis: Emoji[]
|
||||||
|
fields: Field[]
|
||||||
|
noindex?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Emoji {
|
||||||
|
shortcode: string
|
||||||
|
url: string
|
||||||
|
static_url: string
|
||||||
|
visible_in_picker: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Field {
|
||||||
|
name: string
|
||||||
|
value: string
|
||||||
|
verified_at: Date | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Application {
|
||||||
|
name: string
|
||||||
|
website: null | string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MediaAttachment {
|
||||||
|
id: string
|
||||||
|
type: string
|
||||||
|
url: string
|
||||||
|
preview_url: string
|
||||||
|
remote_url: string
|
||||||
|
preview_remote_url: null
|
||||||
|
text_url: null
|
||||||
|
meta: Meta
|
||||||
|
description: null | string
|
||||||
|
blurhash: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Meta {
|
||||||
|
focus?: Focus
|
||||||
|
original: Original
|
||||||
|
small: Original
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Focus {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Original {
|
||||||
|
width: number
|
||||||
|
height: number
|
||||||
|
size: string
|
||||||
|
aspect: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Tag {
|
||||||
|
name: string
|
||||||
|
url: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export enum Visibility {
|
||||||
|
Public = 'public',
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
<script setup>
|
||||||
|
useHead({
|
||||||
|
title: 'Vitesse Nuxt 3',
|
||||||
|
link: [
|
||||||
|
{
|
||||||
|
rel: 'icon', type: 'image/png', href: '/nuxt.png',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NuxtLayout>
|
||||||
|
<NuxtPage />
|
||||||
|
</NuxtLayout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body , #__nuxt{
|
||||||
|
height: 100vh;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.dark {
|
||||||
|
background: #222;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Account } from '~/api-client/types'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
account: Account
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex gap-2>
|
||||||
|
<div p1>
|
||||||
|
<img :src="account.avatar" rounded w-10 h-10>
|
||||||
|
</div>
|
||||||
|
<div flex flex-col>
|
||||||
|
<h4 font-bold>
|
||||||
|
{{ account.display_name }}
|
||||||
|
</h4>
|
||||||
|
<p op50>
|
||||||
|
@{{ account.acct }}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Post } from '~/api-client/types'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
post: Post
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex justify-around px-2>
|
||||||
|
<button flex gap-1 items-center>
|
||||||
|
<div i-ri:chat-3-line />
|
||||||
|
<span>{{ post.replies_count }}</span>
|
||||||
|
</button>
|
||||||
|
<button flex gap-1 items-center>
|
||||||
|
<div i-ri:repeat-fill />
|
||||||
|
<span>{{ post.reblogs_count }}</span>
|
||||||
|
</button>
|
||||||
|
<button flex gap-1 items-center>
|
||||||
|
<div i-ri:heart-3-line />
|
||||||
|
<span>{{ post.favourites_count }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { Post } from '~/api-client/types'
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
post: Post
|
||||||
|
}>()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div flex flex-col gap-4 mb-5>
|
||||||
|
<AccountInfo :account="post.account" />
|
||||||
|
<div v-html="post.content" />
|
||||||
|
<PostActions :post="post" />
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { Client } from '~/api-client'
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
host: 'https://mas.to',
|
||||||
|
})
|
||||||
|
|
||||||
|
export function useClient() {
|
||||||
|
return client
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
// for UnoCSS attributify mode compact in Volar
|
||||||
|
// refer: https://github.com/johnsoncodehk/volar/issues/1077#issuecomment-1145361472
|
||||||
|
declare module '@vue/runtime-dom' {
|
||||||
|
interface HTMLAttributes {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
declare module '@vue/runtime-core' {
|
||||||
|
interface AllowedComponentProps {
|
||||||
|
[key: string]: any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export {}
|
|
@ -0,0 +1,15 @@
|
||||||
|
## Layouts
|
||||||
|
|
||||||
|
Vue components in this dir are used as layouts.
|
||||||
|
|
||||||
|
By default, `default.vue` will be used unless an alternative is specified in the route meta.
|
||||||
|
|
||||||
|
```html
|
||||||
|
<script setup lang="ts">
|
||||||
|
definePageMeta({
|
||||||
|
layout: 'home',
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
Learn more on https://v3.nuxtjs.org/guide/directory-structure/layouts
|
|
@ -0,0 +1,5 @@
|
||||||
|
<template>
|
||||||
|
<main class="py-20 px-10">
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
</template>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<main class="py-20 px-10 text-center">
|
||||||
|
<slot />
|
||||||
|
<Footer />
|
||||||
|
<div class="mt-5 mx-auto text-center opacity-25 text-sm">
|
||||||
|
[Home Layout]
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</template>
|
|
@ -0,0 +1,12 @@
|
||||||
|
[build.environment]
|
||||||
|
NPM_FLAGS = "--version"
|
||||||
|
NODE_VERSION = "16"
|
||||||
|
|
||||||
|
[build]
|
||||||
|
publish = "dist"
|
||||||
|
command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm run build"
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from = "/*"
|
||||||
|
to = "/index.html"
|
||||||
|
status = 200
|
|
@ -0,0 +1,18 @@
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
modules: [
|
||||||
|
'@vueuse/nuxt',
|
||||||
|
'@unocss/nuxt',
|
||||||
|
'@pinia/nuxt',
|
||||||
|
'@nuxtjs/color-mode',
|
||||||
|
],
|
||||||
|
experimental: {
|
||||||
|
reactivityTransform: true,
|
||||||
|
inlineSSRStyles: false,
|
||||||
|
},
|
||||||
|
css: [
|
||||||
|
'@unocss/reset/tailwind.css',
|
||||||
|
],
|
||||||
|
colorMode: {
|
||||||
|
classSuffix: '',
|
||||||
|
},
|
||||||
|
})
|
|
@ -0,0 +1,26 @@
|
||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"packageManager": "pnpm@7.9.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxi build",
|
||||||
|
"dev": "nuxi dev",
|
||||||
|
"start": "node .output/server/index.mjs",
|
||||||
|
"lint": "eslint .",
|
||||||
|
"postinstall": "nuxi prepare",
|
||||||
|
"generate": "nuxi generate"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@antfu/eslint-config": "^0.30.1",
|
||||||
|
"@iconify-json/carbon": "^1.1.9",
|
||||||
|
"@iconify-json/ri": "^1.1.3",
|
||||||
|
"@iconify-json/twemoji": "^1.1.5",
|
||||||
|
"@nuxtjs/color-mode": "^3.1.8",
|
||||||
|
"@pinia/nuxt": "^0.4.3",
|
||||||
|
"@unocss/nuxt": "^0.46.5",
|
||||||
|
"@vueuse/nuxt": "^9.5.0",
|
||||||
|
"eslint": "^8.27.0",
|
||||||
|
"nuxt": "^3.0.0-rc.13",
|
||||||
|
"pinia": "^2.0.23",
|
||||||
|
"typescript": "^4.8.4"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const router = useRouter()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<main p="x4 y10" text="center teal-700 dark:gray-200">
|
||||||
|
<div text-4xl>
|
||||||
|
<div i-carbon-warning inline-block />
|
||||||
|
</div>
|
||||||
|
<div>Not found</div>
|
||||||
|
<div>
|
||||||
|
<button btn text-sm m="3 t8" @click="router.back()">
|
||||||
|
Back
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</template>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
const client = useClient()
|
||||||
|
const posts = await client.getPublicTimeline()
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div w-150>
|
||||||
|
<template v-for="post in posts" :key="post.id">
|
||||||
|
<PostCard :post="post" />
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
||||||
|
const startAt = Date.now()
|
||||||
|
let count = 0
|
||||||
|
|
||||||
|
export default defineEventHandler(() => ({
|
||||||
|
pageview: count++,
|
||||||
|
startAt,
|
||||||
|
}))
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"extends": "./.nuxt/tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"strict": true
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
import {
|
||||||
|
defineConfig,
|
||||||
|
presetAttributify,
|
||||||
|
presetIcons,
|
||||||
|
presetTypography,
|
||||||
|
presetUno,
|
||||||
|
presetWebFonts,
|
||||||
|
transformerDirectives,
|
||||||
|
transformerVariantGroup,
|
||||||
|
} from 'unocss'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
shortcuts: [
|
||||||
|
],
|
||||||
|
presets: [
|
||||||
|
presetUno(),
|
||||||
|
presetAttributify(),
|
||||||
|
presetIcons({
|
||||||
|
scale: 1.2,
|
||||||
|
}),
|
||||||
|
presetTypography(),
|
||||||
|
presetWebFonts({
|
||||||
|
fonts: {
|
||||||
|
sans: 'DM Sans',
|
||||||
|
serif: 'DM Serif Display',
|
||||||
|
mono: 'DM Mono',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
transformers: [
|
||||||
|
transformerDirectives(),
|
||||||
|
transformerVariantGroup(),
|
||||||
|
],
|
||||||
|
})
|
Loading…
Reference in New Issue