mirror of
https://github.com/Sevichecc/Urara-Blog.git
synced 2025-04-30 14:29:29 +08:00
new post and merge with upsteam 3a99081
This commit is contained in:
parent
ad830f9463
commit
29fd250ace
52 changed files with 568 additions and 2304 deletions
33
.gitignore
vendored
33
.gitignore
vendored
|
@ -1,15 +1,24 @@
|
||||||
.DS_Store
|
# build output
|
||||||
node_modules
|
|
||||||
.svelte-kit
|
|
||||||
/package
|
|
||||||
src/routes/**/
|
|
||||||
src/routes/*.md
|
|
||||||
static/
|
|
||||||
build
|
build
|
||||||
.vercel_build_output/
|
static
|
||||||
.netlify/
|
.svelte-kit
|
||||||
.env.local
|
.netlify
|
||||||
.env.**.local
|
.vercel_build_output
|
||||||
myblog/urara/2022-06-12-appwrite.md
|
|
||||||
|
# dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# env
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# logs
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# macOS-specific files
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# temp file
|
||||||
|
src/routes/**/+page.svelte.md
|
||||||
|
src/routes/**/+page.md
|
||||||
*.config.js
|
*.config.js
|
||||||
urara.js
|
urara.js
|
|
@ -29,7 +29,7 @@ const remarkUraraFm =
|
||||||
if (!data.fm) data.fm = {}
|
if (!data.fm) data.fm = {}
|
||||||
// Generate slug & path
|
// Generate slug & path
|
||||||
data.fm.slug = filepath
|
data.fm.slug = filepath
|
||||||
data.fm.path = join(dir, `/${name}`.replace('/index', '').replace('.svelte', ''))
|
data.fm.path = join(dir, `/${name}`.replace('/+page', '').replace('.svelte', ''))
|
||||||
// Generate ToC
|
// Generate ToC
|
||||||
if (data.fm.toc !== false) {
|
if (data.fm.toc !== false) {
|
||||||
const [slugs, toc]: [slugs: Slugger, toc: { depth: number; title: string; slug: string }[]] = [new Slugger(), []]
|
const [slugs, toc]: [slugs: Slugger, toc: { depth: number; title: string; slug: string }[]] = [new Slugger(), []]
|
||||||
|
@ -48,15 +48,6 @@ const remarkUraraFm =
|
||||||
if (!data.fm.created) data.fm.created = ctime
|
if (!data.fm.created) data.fm.created = ctime
|
||||||
if (!data.fm.updated) data.fm.updated = mtime
|
if (!data.fm.updated) data.fm.updated = mtime
|
||||||
}
|
}
|
||||||
// Remark FFF Experimental (Hugo -> MDsveX)
|
|
||||||
Object.entries({
|
|
||||||
image: 'images',
|
|
||||||
tags: 'category',
|
|
||||||
bookmark_of: 'bookmarkOf',
|
|
||||||
like_of: 'likeOf',
|
|
||||||
repost_of: 'repostOf',
|
|
||||||
in_reply_to: 'inReplyTo'
|
|
||||||
}).forEach(([output, input]: string[]) => (data.fm = { ...data.fm, [output]: data.fm![input] }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Better type definitions needed
|
// Better type definitions needed
|
||||||
|
|
27
package.json
27
package.json
|
@ -29,8 +29,8 @@
|
||||||
"zhlint": "zhlint urara/*/*.md --fix && zhlint urara/*.md --fix"
|
"zhlint": "zhlint urara/*/*.md --fix && zhlint urara/*.md --fix"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/heroicons-outline": "^1.1.2",
|
"@iconify-json/heroicons-outline": "^1.1.4",
|
||||||
"@iconify-json/heroicons-solid": "^1.1.2",
|
"@iconify-json/heroicons-solid": "^1.1.5",
|
||||||
"@iconify-json/ic": "^1.1.9",
|
"@iconify-json/ic": "^1.1.9",
|
||||||
"@iconify-json/simple-icons": "1.1.21",
|
"@iconify-json/simple-icons": "1.1.21",
|
||||||
"@iconify-json/material-symbols": "1.1.14",
|
"@iconify-json/material-symbols": "1.1.14",
|
||||||
|
@ -39,19 +39,19 @@
|
||||||
"@sveltejs/adapter-auto": "1.0.0-next.64",
|
"@sveltejs/adapter-auto": "1.0.0-next.64",
|
||||||
"@sveltejs/adapter-node": "1.0.0-next.86",
|
"@sveltejs/adapter-node": "1.0.0-next.86",
|
||||||
"@sveltejs/adapter-static": "1.0.0-next.39",
|
"@sveltejs/adapter-static": "1.0.0-next.39",
|
||||||
"@sveltejs/kit": "1.0.0-next.405",
|
"@sveltejs/kit": "1.0.0-next.456",
|
||||||
"@tailwindcss/typography": "^0.5.4",
|
"@tailwindcss/typography": "^0.5.4",
|
||||||
"@types/node": "^18.7.8",
|
"@types/node": "^18.7.14",
|
||||||
"@types/unist": "^2.0.6",
|
"@types/unist": "^2.0.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.33.1",
|
"@typescript-eslint/eslint-plugin": "^5.36.1",
|
||||||
"@typescript-eslint/parser": "^5.33.1",
|
"@typescript-eslint/parser": "^5.36.1",
|
||||||
"autoprefixer": "^10.4.8",
|
"autoprefixer": "^10.4.8",
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
"chokidar": "^3.5.3",
|
"chokidar": "^3.5.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"cssnano": "^5.1.13",
|
"cssnano": "^5.1.13",
|
||||||
"daisyui": "^2.24.0",
|
"daisyui": "^2.24.0",
|
||||||
"eslint": "^8.22.0",
|
"eslint": "^8.23.0",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-svelte3": "^4.0.0",
|
"eslint-plugin-svelte3": "^4.0.0",
|
||||||
"fenceparser": "^2.2.0",
|
"fenceparser": "^2.2.0",
|
||||||
|
@ -68,19 +68,20 @@
|
||||||
"rehype-slug": "^5.0.1",
|
"rehype-slug": "^5.0.1",
|
||||||
"remark": "^14.0.2",
|
"remark": "^14.0.2",
|
||||||
"remark-footnotes": "~2.0.0",
|
"remark-footnotes": "~2.0.0",
|
||||||
|
"remark-fff": "^0.3.0-alpha.1",
|
||||||
"shiki-twoslash": "^3.1.0",
|
"shiki-twoslash": "^3.1.0",
|
||||||
"svelte": "^3.49.0",
|
"svelte": "^3.49.0",
|
||||||
"svelte-bricks": "^0.1.7",
|
"svelte-bricks": "^0.1.7",
|
||||||
"svelte-check": "^2.8.1",
|
"svelte-check": "^2.9.0",
|
||||||
"svelte-preprocess": "^4.10.7",
|
"svelte-preprocess": "^4.10.7",
|
||||||
"svelte-typeahead": "^4.2.4",
|
"svelte-typeahead": "^4.2.4",
|
||||||
"tailwindcss": "^3.1.8",
|
"tailwindcss": "^3.1.8",
|
||||||
"tslib": "^2.4.0",
|
"tslib": "^2.4.0",
|
||||||
"typescript": "^4.7.4",
|
"typescript": "^4.8.2",
|
||||||
"unist-util-visit": "^4.1.0",
|
"unist-util-visit": "^4.1.1",
|
||||||
"unocss": "^0.45.8",
|
"unocss": "^0.45.13",
|
||||||
"vite": "^3.0.9",
|
"vite": "^3.1.0-beta.1",
|
||||||
"vite-plugin-pwa": "^0.12.3",
|
"vite-plugin-pwa": "^0.12.4",
|
||||||
"workbox-window": "^6.5.4"
|
"workbox-window": "^6.5.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
530
pnpm-lock.yaml
530
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { dev } from '$app/env'
|
import { dev } from'$app/environment'
|
||||||
let className = undefined
|
let className = undefined
|
||||||
export { className as class }
|
export { className as class }
|
||||||
export let src = undefined
|
export let src = undefined
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { dev } from '$app/env'
|
import { dev } from'$app/environment'
|
||||||
import { head } from '$lib/config/general'
|
import { head } from '$lib/config/general'
|
||||||
import { site } from '$lib/config/site'
|
import { site } from '$lib/config/site'
|
||||||
import OpenGraph from '$lib/components/head_opengraph.svelte'
|
import OpenGraph from '$lib/components/head_opengraph.svelte'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser, dev } from '$app/env'
|
import { browser, dev } from '$app/environment'
|
||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { site } from '$lib/config/site'
|
import { site } from '$lib/config/site'
|
||||||
import { theme } from '$lib/config/general'
|
import { theme } from '$lib/config/general'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { browser } from '$app/env'
|
import { browser } from '$app/environment'
|
||||||
import { post as postConfig } from '$lib/config/post'
|
import { post as postConfig } from '$lib/config/post'
|
||||||
import { posts as storedPosts } from '$lib/stores/posts'
|
import { posts as storedPosts } from '$lib/stores/posts'
|
||||||
import { title as storedTitle } from '$lib/stores/title'
|
import { title as storedTitle } from '$lib/stores/title'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { browser } from '$app/env'
|
import { browser } from'$app/environment'
|
||||||
import Card from '$lib/components/post_card.svelte'
|
import Card from '$lib/components/post_card.svelte'
|
||||||
import Head from '$lib/components/head.svelte'
|
import Head from '$lib/components/head.svelte'
|
||||||
import Toc from '$lib/components/post_toc.svelte'
|
import Toc from '$lib/components/post_toc.svelte'
|
||||||
|
|
|
@ -136,6 +136,7 @@ export const head: HeadConfig = {
|
||||||
'<meta name="baiduspider" content="noindex,noarchive">',
|
'<meta name="baiduspider" content="noindex,noarchive">',
|
||||||
// Microsub
|
// Microsub
|
||||||
'<link rel="microsub" href="https://aperture.p3k.io/microsub/761">'
|
'<link rel="microsub" href="https://aperture.p3k.io/microsub/761">'
|
||||||
|
|
||||||
],
|
],
|
||||||
me: ['https://kongwoo.icu/@seviche']
|
me: ['https://kongwoo.icu/@seviche']
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,11 @@
|
||||||
<script lang="ts" context="module">
|
|
||||||
import type { Load } from './__types'
|
|
||||||
export const load: Load = ({ url: { pathname }, error, status }) => ({ props: { pathname, error, status } })
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { page } from '$app/stores'
|
||||||
import Head from '$lib/components/head.svelte'
|
import Head from '$lib/components/head.svelte'
|
||||||
import Footer from '$lib/components/footer.svelte'
|
import Footer from '$lib/components/footer.svelte'
|
||||||
export let pathname: string
|
console.error($page.status, $page.error.message)
|
||||||
export let error: Error
|
|
||||||
export let status: string
|
|
||||||
console.error(status, error.message)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Head page={{ title: status ?? '404', path: pathname ?? '/404' }} />
|
<Head page={{ title: $page.status.toString() ?? '404', path: $page.url.pathname }} />
|
||||||
|
|
||||||
<div class="flex flex-col flex-nowrap justify-center xl:flex-row xl:flex-wrap">
|
<div class="flex flex-col flex-nowrap justify-center xl:flex-row xl:flex-wrap">
|
||||||
<div class="flex-none w-full max-w-screen-md mx-auto xl:mx-0">
|
<div class="flex-none w-full max-w-screen-md mx-auto xl:mx-0">
|
||||||
|
@ -22,9 +15,9 @@
|
||||||
class="card bg-base-100 rounded-none md:rounded-box shadow-xl md:mb-8 z-10">
|
class="card bg-base-100 rounded-none md:rounded-box shadow-xl md:mb-8 z-10">
|
||||||
<main itemprop="articleBody" class="card-body prose urara-prose">
|
<main itemprop="articleBody" class="card-body prose urara-prose">
|
||||||
<h1 class="opacity-20 text-6xl md:text-[12rem] -mt-2 mb-0">
|
<h1 class="opacity-20 text-6xl md:text-[12rem] -mt-2 mb-0">
|
||||||
{status ?? '404'}
|
{$page.status ?? '404'}
|
||||||
</h1>
|
</h1>
|
||||||
<h2 class="-mt-12 md:-mt-24">{error.message ?? 'Not found'}</h2>
|
<h2 class="-mt-12 md:-mt-24">{$page.error.message ?? 'Not found'}</h2>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<a href="/" class="btn btn-neutral no-underline shadow-xl hover:shadow-2xl mt-8">
|
<a href="/" class="btn btn-neutral no-underline shadow-xl hover:shadow-2xl mt-8">
|
||||||
<span class="i-heroicons-outline-home -ml-1 mr-2" />
|
<span class="i-heroicons-outline-home -ml-1 mr-2" />
|
|
@ -1,17 +1,7 @@
|
||||||
<script lang="ts" context="module">
|
|
||||||
import type { Load } from './__types'
|
|
||||||
export const prerender = true
|
|
||||||
export const load: Load = async ({ url, fetch }) => ({
|
|
||||||
props: {
|
|
||||||
path: url.pathname,
|
|
||||||
res: await fetch('/posts.json').then(res => res.json())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import type { LayoutData } from './$types'
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { browser, dev } from '$app/env'
|
import { browser, dev } from '$app/environment'
|
||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { genTags } from '$lib/utils/posts'
|
import { genTags } from '$lib/utils/posts'
|
||||||
import { posts, tags } from '$lib/stores/posts'
|
import { posts, tags } from '$lib/stores/posts'
|
||||||
|
@ -20,10 +10,11 @@
|
||||||
import Header from '$lib/components/header.svelte'
|
import Header from '$lib/components/header.svelte'
|
||||||
import 'uno.css'
|
import 'uno.css'
|
||||||
import '../app.css'
|
import '../app.css'
|
||||||
export let res: Urara.Post[]
|
|
||||||
export let path: string
|
export let data: LayoutData
|
||||||
posts.set(res)
|
|
||||||
tags.set(genTags(res))
|
posts.set(data.res)
|
||||||
|
tags.set(genTags(data.res))
|
||||||
onMount(
|
onMount(
|
||||||
() =>
|
() =>
|
||||||
!dev &&
|
!dev &&
|
||||||
|
@ -37,9 +28,9 @@
|
||||||
|
|
||||||
<Head />
|
<Head />
|
||||||
|
|
||||||
<Header {path} />
|
<Header path={data.path} />
|
||||||
|
|
||||||
{#key path}
|
{#key data.path}
|
||||||
<div
|
<div
|
||||||
class="bg-base-100 md:bg-base-200 min-h-screen pt-16 md:pb-8 lg:pb-16"
|
class="bg-base-100 md:bg-base-200 min-h-screen pt-16 md:pb-8 lg:pb-16"
|
||||||
in:fly={{ y: 100, duration: 300, delay: 300 }}
|
in:fly={{ y: 100, duration: 300, delay: 300 }}
|
6
src/routes/+layout.ts
Normal file
6
src/routes/+layout.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
import type { LayoutLoad } from './$types'
|
||||||
|
export const prerender = true
|
||||||
|
export const load: LayoutLoad = async ({ url, fetch }) => ({
|
||||||
|
path: url.pathname,
|
||||||
|
res: await fetch('/posts.json').then(res => res.json())
|
||||||
|
})
|
|
@ -2,7 +2,7 @@
|
||||||
import { onMount } from 'svelte'
|
import { onMount } from 'svelte'
|
||||||
import { fly } from 'svelte/transition'
|
import { fly } from 'svelte/transition'
|
||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import { browser } from '$app/env'
|
import { browser } from '$app/environment'
|
||||||
import { posts as storedPosts, tags as storedTags } from '$lib/stores/posts'
|
import { posts as storedPosts, tags as storedTags } from '$lib/stores/posts'
|
||||||
import { title as storedTitle } from '$lib/stores/title'
|
import { title as storedTitle } from '$lib/stores/title'
|
||||||
import Head from '$lib/components/head.svelte'
|
import Head from '$lib/components/head.svelte'
|
||||||
|
@ -10,7 +10,6 @@
|
||||||
import Post from '$lib/components/post_card.svelte'
|
import Post from '$lib/components/post_card.svelte'
|
||||||
// import Post from '$lib/components/index_post.svelte'
|
// import Post from '$lib/components/index_post.svelte'
|
||||||
import Profile from '$lib/components/index_profile.svelte'
|
import Profile from '$lib/components/index_profile.svelte'
|
||||||
import RemoteFollow from '$lib/components/extra/follow.svelte'
|
|
||||||
|
|
||||||
let allPosts: Urara.Post[]
|
let allPosts: Urara.Post[]
|
||||||
let allTags: string[]
|
let allTags: string[]
|
||||||
|
@ -125,5 +124,3 @@
|
||||||
{/key}
|
{/key}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<RemoteFollow />
|
|
|
@ -1,12 +1,12 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
import type { RequestHandler } from './$types'
|
||||||
import { site } from '$lib/config/site'
|
import { site } from '$lib/config/site'
|
||||||
import { feed } from '$lib/config/general'
|
import { feed } from '$lib/config/general'
|
||||||
import { favicon } from '$lib/config/icon'
|
import { favicon } from '$lib/config/icon'
|
||||||
import { genPosts, genTags } from '$lib/utils/posts'
|
import { genPosts, genTags } from '$lib/utils/posts'
|
||||||
|
|
||||||
const render = async (
|
const render = (
|
||||||
posts = genPosts({ postHtml: true, postLimit: feed.limit, filterUnlisted: true })
|
posts = genPosts({ postHtml: true, postLimit: feed.limit, filterUnlisted: true })
|
||||||
): Promise<string> => `<?xml version='1.0' encoding='utf-8'?>
|
): string => `<?xml version='1.0' encoding='utf-8'?>
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
<id>${site.protocol + site.domain}/</id>
|
<id>${site.protocol + site.domain}/</id>
|
||||||
<title><![CDATA[${site.title}]]></title>${site.subtitle ? `\n <subtitle><![CDATA[${site.subtitle}]]></subtitle>` : ''}${
|
<title><![CDATA[${site.title}]]></title>${site.subtitle ? `\n <subtitle><![CDATA[${site.subtitle}]]></subtitle>` : ''}${
|
||||||
|
@ -41,9 +41,10 @@ const render = async (
|
||||||
.join('')}
|
.join('')}
|
||||||
</feed>`
|
</feed>`
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => ({
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = async () =>
|
||||||
|
new Response(render(), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/atom+xml; charset=utf-8'
|
'content-type': 'application/atom+xml; charset=utf-8'
|
||||||
},
|
}
|
||||||
body: await render()
|
})
|
||||||
})
|
|
|
@ -1,10 +1,10 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
import type { RequestHandler } from './$types'
|
||||||
import { site } from '$lib/config/site'
|
import { site } from '$lib/config/site'
|
||||||
import { feed } from '$lib/config/general'
|
import { feed } from '$lib/config/general'
|
||||||
import { favicon, any } from '$lib/config/icon'
|
import { favicon, any } from '$lib/config/icon'
|
||||||
import { genPosts } from '$lib/utils/posts'
|
import { genPosts } from '$lib/utils/posts'
|
||||||
|
|
||||||
const render = async (posts = genPosts({ postHtml: true, postLimit: feed.limit, filterUnlisted: true })) => ({
|
const render = (posts = genPosts({ postHtml: true, postLimit: feed.limit, filterUnlisted: true })) => ({
|
||||||
version: 'https://jsonfeed.org/version/1.1',
|
version: 'https://jsonfeed.org/version/1.1',
|
||||||
title: site.title,
|
title: site.title,
|
||||||
home_page_url: site.protocol + site.domain,
|
home_page_url: site.protocol + site.domain,
|
||||||
|
@ -41,9 +41,10 @@ const render = async (posts = genPosts({ postHtml: true, postLimit: feed.limit,
|
||||||
}))
|
}))
|
||||||
})
|
})
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => ({
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = async () =>
|
||||||
|
new Response(JSON.stringify(render(), null, 2), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/feed+json; charset=utf-8'
|
'content-type': 'application/feed+json; charset=utf-8'
|
||||||
},
|
}
|
||||||
body: JSON.stringify(await render(), null, 2)
|
})
|
||||||
})
|
|
|
@ -1,32 +0,0 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
|
||||||
import { site } from '$lib/config/site'
|
|
||||||
import { any, maskable } from '$lib/config/icon'
|
|
||||||
|
|
||||||
export const GET: RequestHandler = () => ({
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/manifest+json; charset=utf-8'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(
|
|
||||||
{
|
|
||||||
name: site.title,
|
|
||||||
short_name: site.title,
|
|
||||||
lang: site.lang,
|
|
||||||
description: site.description,
|
|
||||||
id: site.protocol + site.domain + '/',
|
|
||||||
start_url: '/',
|
|
||||||
scope: '/',
|
|
||||||
display: 'standalone',
|
|
||||||
orientation: 'portrait',
|
|
||||||
background_color: site.themeColor,
|
|
||||||
theme_color: site.themeColor,
|
|
||||||
icons: [
|
|
||||||
...Object.values(any)
|
|
||||||
.filter(icon => icon.sizes !== '180x180')
|
|
||||||
.map(icon => ({ ...icon, purpose: 'any' })),
|
|
||||||
...Object.values(maskable).map(icon => ({ ...icon, purpose: 'maskable' }))
|
|
||||||
]
|
|
||||||
},
|
|
||||||
null,
|
|
||||||
2
|
|
||||||
)
|
|
||||||
})
|
|
36
src/routes/manifest.webmanifest/+server.ts
Normal file
36
src/routes/manifest.webmanifest/+server.ts
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
import type { RequestHandler } from './$types'
|
||||||
|
import { site } from '$lib/config/site'
|
||||||
|
import { any, maskable } from '$lib/config/icon'
|
||||||
|
|
||||||
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = () =>
|
||||||
|
new Response(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
name: site.title,
|
||||||
|
short_name: site.title,
|
||||||
|
lang: site.lang,
|
||||||
|
description: site.description,
|
||||||
|
id: site.protocol + site.domain + '/',
|
||||||
|
start_url: '/',
|
||||||
|
scope: '/',
|
||||||
|
display: 'standalone',
|
||||||
|
orientation: 'portrait',
|
||||||
|
background_color: site.themeColor,
|
||||||
|
theme_color: site.themeColor,
|
||||||
|
icons: [
|
||||||
|
...Object.values(any)
|
||||||
|
.filter(icon => icon.sizes !== '180x180')
|
||||||
|
.map(icon => ({ ...icon, purpose: 'any' })),
|
||||||
|
...Object.values(maskable).map(icon => ({ ...icon, purpose: 'maskable' }))
|
||||||
|
]
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/manifest+json; charset=utf-8'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
|
@ -1,9 +0,0 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
|
||||||
import { genPosts } from '$lib/utils/posts'
|
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => ({
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json; charset=utf-8'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(genPosts(), null, 2)
|
|
||||||
})
|
|
10
src/routes/posts.json/+server.ts
Normal file
10
src/routes/posts.json/+server.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import type { RequestHandler } from './$types'
|
||||||
|
import { genPosts } from '$lib/utils/posts'
|
||||||
|
|
||||||
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = async () =>
|
||||||
|
new Response(JSON.stringify(genPosts(), null, 2), {
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json; charset=utf-8'
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,8 +1,8 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
import type { RequestHandler } from './$types'
|
||||||
import { site } from '$lib/config/site'
|
import { site } from '$lib/config/site'
|
||||||
import { genPosts } from '$lib/utils/posts'
|
import { genPosts } from '$lib/utils/posts'
|
||||||
|
|
||||||
const render = async (): Promise<string> => `<?xml version='1.0' encoding='utf-8'?>
|
const render = (): string => `<?xml version='1.0' encoding='utf-8'?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
<url>
|
<url>
|
||||||
<loc>${site.protocol + site.domain}</loc>
|
<loc>${site.protocol + site.domain}</loc>
|
||||||
|
@ -19,9 +19,10 @@ const render = async (): Promise<string> => `<?xml version='1.0' encoding='utf-8
|
||||||
.join('')}
|
.join('')}
|
||||||
</urlset>`
|
</urlset>`
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => ({
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = async () =>
|
||||||
|
new Response(render(), {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/xml; charset=utf-8'
|
'content-type': 'application/xml; charset=utf-8'
|
||||||
},
|
}
|
||||||
body: await render()
|
})
|
||||||
})
|
|
|
@ -1,9 +0,0 @@
|
||||||
import type { RequestHandler } from '@sveltejs/kit'
|
|
||||||
import { genPosts, genTags } from '$lib/utils/posts'
|
|
||||||
|
|
||||||
export const GET: RequestHandler = async () => ({
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json; charset=utf-8'
|
|
||||||
},
|
|
||||||
body: JSON.stringify(genTags(genPosts()), null, 2)
|
|
||||||
})
|
|
10
src/routes/tags.json/+server.ts
Normal file
10
src/routes/tags.json/+server.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import type { RequestHandler } from './$types'
|
||||||
|
import { genPosts, genTags } from '$lib/utils/posts'
|
||||||
|
|
||||||
|
export const prerender = true
|
||||||
|
export const GET: RequestHandler = async () =>
|
||||||
|
new Response(JSON.stringify(genTags(genPosts()), null, 2), {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json; charset=utf-8'
|
||||||
|
}
|
||||||
|
})
|
|
@ -1,12 +1,13 @@
|
||||||
// sveltekit config type
|
// sveltekit config type
|
||||||
import type { Config } from '@sveltejs/kit'
|
import type { Config } from '@sveltejs/kit'
|
||||||
// svelte preprocess
|
// svelte adapter
|
||||||
import preprocess from 'svelte-preprocess'
|
|
||||||
import adapterAuto from '@sveltejs/adapter-auto'
|
import adapterAuto from '@sveltejs/adapter-auto'
|
||||||
import adapterNode from '@sveltejs/adapter-node'
|
import adapterNode from '@sveltejs/adapter-node'
|
||||||
import adapterStatic from '@sveltejs/adapter-static'
|
import adapterStatic from '@sveltejs/adapter-static'
|
||||||
|
// svelte preprocessor
|
||||||
import { mdsvex } from 'mdsvex'
|
import { mdsvex } from 'mdsvex'
|
||||||
import mdsvexConfig from './mdsvex.config.js'
|
import mdsvexConfig from './mdsvex.config.js'
|
||||||
|
import preprocess from 'svelte-preprocess'
|
||||||
|
|
||||||
const defineConfig = (config: Config) => config
|
const defineConfig = (config: Config) => config
|
||||||
|
|
||||||
|
@ -23,7 +24,6 @@ export default defineConfig({
|
||||||
assets: 'build',
|
assets: 'build',
|
||||||
fallback: undefined
|
fallback: undefined
|
||||||
}),
|
}),
|
||||||
csp: { mode: 'auto' },
|
csp: { mode: 'auto' }
|
||||||
prerender: { default: true }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,32 +1,14 @@
|
||||||
// tailwind config type
|
// @ts-ignore Could not find a declaration file for module '@tailwindcss/typography'.
|
||||||
import type { TailwindConfig } from 'tailwindcss/tailwind-config'
|
|
||||||
// @ts-ignore TS2305: Module 'tailwindcss/plugin' has no exported member 'TailwindPluginWithoutOptions'.
|
|
||||||
import type { TailwindPluginWithoutOptions } from 'tailwindcss/plugin'
|
|
||||||
// tailwind plugins
|
|
||||||
import typography from '@tailwindcss/typography'
|
import typography from '@tailwindcss/typography'
|
||||||
|
// @ts-ignore Could not find a declaration file for module 'daisyui'.
|
||||||
import daisyui from 'daisyui'
|
import daisyui from 'daisyui'
|
||||||
|
|
||||||
interface Config extends TailwindConfig {
|
export default {
|
||||||
daisyui?: {
|
|
||||||
styled?: boolean
|
|
||||||
themes?: boolean | string[]
|
|
||||||
base?: boolean
|
|
||||||
utils?: boolean
|
|
||||||
logs?: boolean
|
|
||||||
rtl?: boolean
|
|
||||||
darkTheme?: string
|
|
||||||
prefix?: string
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const defineConfig = (config: Config) => config
|
|
||||||
|
|
||||||
export default defineConfig({
|
|
||||||
content: ['./src/**/*.{html,md,js,svelte,ts}'],
|
content: ['./src/**/*.{html,md,js,svelte,ts}'],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {}
|
extend: {}
|
||||||
},
|
},
|
||||||
plugins: [typography as TailwindPluginWithoutOptions, daisyui as TailwindPluginWithoutOptions],
|
plugins: [typography, daisyui],
|
||||||
daisyui: {
|
daisyui: {
|
||||||
themes: [
|
themes: [
|
||||||
'light',
|
'light',
|
||||||
|
@ -60,4 +42,4 @@ export default defineConfig({
|
||||||
'winter'
|
'winter'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
}
|
2
urara.ts
2
urara.ts
|
@ -9,7 +9,7 @@ import chokidar from 'chokidar'
|
||||||
import chalk from 'chalk'
|
import chalk from 'chalk'
|
||||||
|
|
||||||
const config = {
|
const config = {
|
||||||
extensions: ['svelte', 'md', 'js', 'ts'],
|
extensions: ['md'],
|
||||||
catch: ['ENOENT', 'EEXIST']
|
catch: ['ENOENT', 'EEXIST']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,132 +0,0 @@
|
||||||
---
|
|
||||||
title: Overview of User Experience Design
|
|
||||||
summary: Introduction to User Experience Design|Week1
|
|
||||||
created: 2021-11-08T10:54:40+08:00
|
|
||||||
# categories:
|
|
||||||
# - UX学习笔记
|
|
||||||
# - Introduction to User Experience Design
|
|
||||||
tags:
|
|
||||||
- UX
|
|
||||||
---
|
|
||||||
|
|
||||||
## 课程简介
|
|
||||||
|
|
||||||
这是一门在 [Coursera](https://www.coursera.org/learn/user-experience-design) 上的 UX 课程,共有五个星期的内容,讲了 UX 的基本概念和实际操作流程,主要侧重用户研究方面,也讲了很多和设计心理学有关的内容,很适合 UX 入门。
|
|
||||||
|
|
||||||
我将按照课程内容的划分,分别发布五个 weeks 的笔记,这是第一篇。
|
|
||||||
|
|
||||||
原笔记是在 Notion 上写的,我喜欢用 Notion 里面的 toggle 效果,用“提问”-“答案”的形式来启发思考,但是博客这里用折叠文本比较麻烦,所以直接列出来了
|
|
||||||
|
|
||||||
## Week 1 笔记
|
|
||||||
|
|
||||||
### 什么是 ux?
|
|
||||||
|
|
||||||
> User Experience design is design that is user centered。The goal is to design artifacts that allow the users to meet their needs in the most effective efficient and satisfying manner。
|
|
||||||
>
|
|
||||||
> **以用户为中心的设计。目标是轻松高效地满足用户的需求。**
|
|
||||||
|
|
||||||
### 用户体验设计的核心概念
|
|
||||||
|
|
||||||
> “用户使用界面来完成任务”
|
|
||||||
|
|
||||||
通过理解用户以及他们要完成的任务,以便设计出最好的界面 (interface)
|
|
||||||
|
|
||||||
### 什么是用户
|
|
||||||
|
|
||||||
这里的“用户”是指使用一些技术来达到目的的个体
|
|
||||||
|
|
||||||
### 什么是界面
|
|
||||||
|
|
||||||
有输入、输出、系统,于此同时,每个输入都会导致一个期望的输出:
|
|
||||||

|
|
||||||
个人使用界面的能力与个人特征、群体、社会有关
|
|
||||||

|
|
||||||
|
|
||||||
### 用户体验设计的目标
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
**设计“能用”并且“好用”的界面**
|
|
||||||
|
|
||||||
- “**能用**”的意思是:它可以让用户完成一个任务。在图中,这个系统 (S) 就产生了期望的成果 (Output)
|
|
||||||
- “**好用**”的意思是:用户可以有效高效甚至满意地达成这项任务。在我们的图表中,这需要轻松快速地输入 (Input) 并且输出 (Output) 的结果有效的完成了任务
|
|
||||||
|
|
||||||
### 界面设计环 (四个步骤)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### Step1:Requirements Gathering 收集需求
|
|
||||||
|
|
||||||
- Understanding the user and what her goals are,What are the current practices
|
|
||||||
- This step can also be thought of as understanding the**“problem space”**- what is hindering the completion of the task how can the task or process be improved
|
|
||||||
- A whole host of techniques are presented that allow the designer to collect data about the user,her goals and current practices
|
|
||||||
|
|
||||||
#### Step 2:Design Alternatives 设计方案
|
|
||||||
|
|
||||||
- Once you understand the users,their goals,and their current practices (e.i., the problem space) you are able to take this data and **develop various design options** that will improve the user experience
|
|
||||||
|
|
||||||
#### Step 3:Prototyping 原型
|
|
||||||
|
|
||||||
- Techniques for modeling the novel designs before a final version is produced
|
|
||||||
|
|
||||||
#### Step 4:Evaluation 评估测试
|
|
||||||
|
|
||||||
- A set of techniques for ascertaining that your design meets the needs of the user
|
|
||||||
|
|
||||||
### 什么样的界面是“实用”的?
|
|
||||||
|
|
||||||
“实用性”指的是有效、高效并且让用户觉得满意的。
|
|
||||||
|
|
||||||
> 如果用户能够理解怎样的输入 (Input) 会带来所需的输出 (Output) 那么这个界面就是实用的
|
|
||||||
|
|
||||||
### 好设计的三个特征
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### 1 - Affordance (示能)
|
|
||||||
|
|
||||||
> 指一个物理对象与人之间的关系
|
|
||||||
>
|
|
||||||
> (无论是动物还是人类,甚至机器和机器人,他们之间发生的任何交互作用)
|
|
||||||
|
|
||||||
是指可以感知到的事物的实际属性,主要是那些决定事物如何被使用的基本属性 (看看你的智能手机,我们会看到很多种功能,例如按键,可以感知到可以被按。)
|
|
||||||
|
|
||||||
#### 2 - Signifiers (意符)
|
|
||||||
|
|
||||||
> 能告诉人们正确操作方式的任何可感知的标记或声音。
|
|
||||||
|
|
||||||
示能决定可能进行哪些操作,意符则点名操作的位置。
|
|
||||||
|
|
||||||
#### 3 - Feedback (反馈)
|
|
||||||
|
|
||||||
> 一些让你知道系统正在处理你的要求的方式
|
|
||||||
|
|
||||||
反馈需要将用户信息发送回来其中包括哪些系统输入的信息已发生它跟我们沟通操作结果
|
|
||||||
|
|
||||||
- 输入:示能、意符
|
|
||||||
- 输出:示能
|
|
||||||
|
|
||||||
### 如何与“用户”接洽
|
|
||||||
|
|
||||||
注意礼貌、着装
|
|
||||||
|
|
||||||
#### 三个步骤
|
|
||||||
|
|
||||||
**1 - 介绍**
|
|
||||||
|
|
||||||
- 简要概述目标
|
|
||||||
- 坦率:让用户知道该会话的目标是什么。询问他们坦率的意见。
|
|
||||||
- 保密:说明交互内容是保密的。
|
|
||||||
- 自愿:在介绍期间,向用户解释他们的参与完全是自愿的。他们可以随时停止参与。如果他们希望停止参与,这不会消极地影响他们与你的公司或机构的关系。这一部分是很重要的,它能让用户放心并能够不受约束,因为你可能代表一个在社区中具有较高知名度的实体
|
|
||||||
- 开放:让他们知道,没有正确或错误的答案,他们应该简单直接地向你提供反馈和意见
|
|
||||||
|
|
||||||
**2 - 交流**
|
|
||||||
|
|
||||||
- 中立态度、语气轻松专业。
|
|
||||||
- 如果形式允许,鼓励详细阐述意外或有趣的信息
|
|
||||||
- 保持对交流过程的控制,尽量覆盖所有话题
|
|
||||||
|
|
||||||
**3 - 结束**
|
|
||||||
|
|
||||||
- 在会话结束时,提醒他们有关交互的目标和您打算如何处理他们提供的数据。
|
|
||||||
- 询问他们是否还有需要补充的内容。
|
|
|
@ -1,407 +0,0 @@
|
||||||
---
|
|
||||||
title: Requirement Gathering
|
|
||||||
summary: Introduction to User Experience Design|Week2
|
|
||||||
created: 2021-11-09T22:26:49+08:00
|
|
||||||
categories:
|
|
||||||
- UX学习笔记
|
|
||||||
- Introduction to User Experience Design
|
|
||||||
tags:
|
|
||||||
- UX
|
|
||||||
---
|
|
||||||
|
|
||||||
## **Overview**
|
|
||||||
|
|
||||||
- **设计流程的第一步**
|
|
||||||
|
|
||||||
了解用户当前是如何完成任务的
|
|
||||||
|
|
||||||
- **需求收集的目标是什么?**
|
|
||||||
|
|
||||||
理解问题域
|
|
||||||
|
|
||||||
- **问题域(problem space)包含什么?**
|
|
||||||
|
|
||||||
1. 谁是我们的用户
|
|
||||||
2. 什么时候使用产品、在什么地点、为什么、以及他们当前如何实现目标任务
|
|
||||||
3. 用户所认为的当前存在的问题是什么
|
|
||||||
4. 以及用户自己关于如何改进任务流程的心愿清单
|
|
||||||
|
|
||||||
- **需求收集的陷井**
|
|
||||||
|
|
||||||
设计师可能会直接开始设计可供选择的设计品,尽管他们尚未完全了解任务,用户以及用户如何实现任务 换句话说,他们急于直奔主题了 他们在没有取得用户数据的基础上就开始设计了
|
|
||||||
|
|
||||||
- **设计是一个系统性的数据驱动的过程**
|
|
||||||
|
|
||||||
## **Types of Users and Types of Data**
|
|
||||||
|
|
||||||
### 数据类型
|
|
||||||
|
|
||||||
#### 定量
|
|
||||||
|
|
||||||
- 定量数据可以被认为是可以用数字转录的数据, 比如调查数据(用户年龄、性别等等)
|
|
||||||
- 定量分析是依据统计数据,建立数学模型,并用数学模型计算出分析对象的各项指标及其数值的一种方法。
|
|
||||||
|
|
||||||
#### 定性
|
|
||||||
|
|
||||||
- 定性数据更容易被认为是为我们提供专题的信息,可放到叙事语境中(如问卷中的开放性问题)
|
|
||||||
- 定性分析则是主要凭分析者的直觉、经验,凭分析对象过去和现在的延续状况及最新的信息资料,对分析对象的性质、特点、发展变化规律作出判断的一种方法。
|
|
||||||
|
|
||||||
> 设计师通常结合使用两种数据,这种方法称为 _混合方法(Mixed method approach)_
|
|
||||||
|
|
||||||
### 将用户视为利益相关者的三个类型
|
|
||||||
|
|
||||||
**1.主要 Primary**
|
|
||||||
|
|
||||||
主要利益相关者是直接使用设计的人员。这些是设计者最常与之互动的用户,他们被称为**最终用户**
|
|
||||||
|
|
||||||
**2.二级 Secondary**
|
|
||||||
|
|
||||||
不直接使用设计,但可以**间接地使用**,因为他们从中可得到某种输出
|
|
||||||
|
|
||||||
**3.三级 Tertiary**
|
|
||||||
|
|
||||||
可能根本不使用设计 ,但**直接受设计的影响**, 无论是消极还是积极的方式
|
|
||||||
|
|
||||||
### 了解利益相关者的意义
|
|
||||||
|
|
||||||
> 考虑二级和三级利益相关者,也可以帮助我们创造具有创新性的设计,并为我们的客户提供竞争优势。从这个意义上讲了解利益相关者会带来更好的用户体验设计
|
|
||||||
|
|
||||||
## **Discovery Technique Overview**
|
|
||||||
|
|
||||||
### 四种调研方法
|
|
||||||
|
|
||||||
1. 自然观察 (Naturalistic observation)
|
|
||||||
2. 问卷法( Surveys)
|
|
||||||
3. 焦点小组( Focus groups)
|
|
||||||
4. 访谈 (Interviews)
|
|
||||||
|
|
||||||
### 交互程度
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 进行的场景
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 在设计周期中迭代
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## **Naturalistic Observation 自然观察**
|
|
||||||
|
|
||||||
### 是什么
|
|
||||||
|
|
||||||
是在用户自己的环境中,观察用户的行为,不需要询问用户何时何地以及怎样完成既定任务的 设计师会亲自到用户完成任务的地点,并观察他们的行为。
|
|
||||||
|
|
||||||
### 如何做
|
|
||||||
|
|
||||||
- 预期计划
|
|
||||||
- 实地进行
|
|
||||||
- 过程中设计师与用户无交谈
|
|
||||||
|
|
||||||
### 数据
|
|
||||||
|
|
||||||
定性、定量
|
|
||||||
|
|
||||||
### 优点
|
|
||||||
|
|
||||||
- 直接观察用户的行为,随时随地收集数据
|
|
||||||
- 用户的行为习惯真实自然,不受设计师主观影响
|
|
||||||
|
|
||||||
### 缺点
|
|
||||||
|
|
||||||
- **数据收集受设计师主观影响。**
|
|
||||||
|
|
||||||
设计师所收集到的数据,局限于他们个人的收集方式和理解方式。无法核实设计师做出的 假设正确与否
|
|
||||||
|
|
||||||
- **停留表面,看不到深层原因。**
|
|
||||||
|
|
||||||
我们并不知道为什么 用户采取这样的方式完成任务
|
|
||||||
|
|
||||||
### 道德局限
|
|
||||||
|
|
||||||
需要注意用户隐私、匿名化
|
|
||||||
|
|
||||||
### 在设计流程中
|
|
||||||
|
|
||||||
> 基于收集到的数据,进行下一步调研,如问卷、焦点小组等,使问题域更聚焦,探寻真正的问题所在,解释用户行为的原因
|
|
||||||
|
|
||||||
## **Survey 问卷**
|
|
||||||
|
|
||||||
### 是什么
|
|
||||||
|
|
||||||
- 问卷调查的目的是了解用户的观点。
|
|
||||||
- 最常见的是让用户自我报告他们的行为、主观感觉、态度和感受。我们也可以获取他们对于他人的看法
|
|
||||||
|
|
||||||
### 如何做
|
|
||||||
|
|
||||||
- 实地、实验室
|
|
||||||
- 几乎不需要直接和用户交流
|
|
||||||
- 形式:纸质问卷、电子问卷、面对面调查
|
|
||||||
|
|
||||||
### 数据
|
|
||||||
|
|
||||||
#### 1.定性-封闭性问题
|
|
||||||
|
|
||||||
**Closed-ended questions**
|
|
||||||
|
|
||||||
- **顺序回答**
|
|
||||||
- **二分型问题 (dichotomous )**
|
|
||||||
是/否
|
|
||||||
- **李克特评分 (likert scales)**
|
|
||||||
评分 1-5
|
|
||||||
- **排序 (rank)**
|
|
||||||
如按照喜好程度排序
|
|
||||||
- **乱序回答**
|
|
||||||
- 给用户呈现了一系列的问题,这些问题并没有逻辑顺序
|
|
||||||
- 例如,人种学问卷:如性别、 教育程度或者是一些列举项,供用户勾选适用于他们的选项
|
|
||||||
|
|
||||||
#### 2.定量-开放性问题
|
|
||||||
|
|
||||||
**Open-ended questions**
|
|
||||||
|
|
||||||
目的是获取用户简短的回答,包括他们的观点、偏好、态度等
|
|
||||||
|
|
||||||
### 优点
|
|
||||||
|
|
||||||
- 高效收集数据
|
|
||||||
- 数据易于分析
|
|
||||||
|
|
||||||
### 缺点
|
|
||||||
|
|
||||||
- 信息表面化,不能提供深入洞察
|
|
||||||
- 回忆偏倚、社会称许性偏见和样本偏差
|
|
||||||
|
|
||||||
### 在设计流程中
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## **Focus group 焦点小组**
|
|
||||||
|
|
||||||
### 是什么
|
|
||||||
|
|
||||||
- 目的是让用户参与直接对话
|
|
||||||
- 焦点小组在可控的环境中进行,通常是一个房间 在这个充满隐私性的房间里 用户可以自由地分享和讨论自己的观点
|
|
||||||
- 焦点小组能够与参与者产生高度互动,这种程度高于 问卷调查,但是低于采访
|
|
||||||
|
|
||||||
### 如何做
|
|
||||||
|
|
||||||
#### 组成
|
|
||||||
|
|
||||||
- **用户**
|
|
||||||
- 5-10 个用户
|
|
||||||
- 这些用户应能够代表设计师所关注的用户群体
|
|
||||||
- **设计团队**
|
|
||||||
|
|
||||||
**1. 主持人**
|
|
||||||
|
|
||||||
- 一个训练有素的主持人 他负责组织用户讨论的话题
|
|
||||||
- 主持人必须非常擅长深入挖掘,在讨论过程中出现的有价值的主题。但同时也要引导用户的讨论 使之覆盖所需要的主题范围
|
|
||||||
|
|
||||||
**2. 记录员**
|
|
||||||
|
|
||||||
- 负责记录用户和主持人之间的谈话要点
|
|
||||||
|
|
||||||
**3. 媒介记录员(可选)**
|
|
||||||
|
|
||||||
- 使用录音或者 录像设备进行记录
|
|
||||||
|
|
||||||
- **流程**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 数据
|
|
||||||
|
|
||||||
- **定性**
|
|
||||||
|
|
||||||
- 对话过程中记录员写下的一系列笔记
|
|
||||||
- 完整的焦点小组对话脚本
|
|
||||||
- 对焦点小组的分析
|
|
||||||
|
|
||||||
- **定量**
|
|
||||||
|
|
||||||
- 可能会在焦点小组一开始进行收集 (例如收集用户的人种学统计信息,或者捕捉关于用户态度的原始问卷调查信息,以及用户对于目标话题的观点)
|
|
||||||
- 主持人应当善于运用这些数据快速开始对话
|
|
||||||
|
|
||||||
### 优点
|
|
||||||
|
|
||||||
- 能够在短时间内收集到关于所感兴趣话题的海量数据
|
|
||||||
- 充满活力的小组讨论 或许能够激发出不一样的结果 这些结果是一对一访谈无法得到的
|
|
||||||
|
|
||||||
### 缺点
|
|
||||||
|
|
||||||
- 需要设计团队去执行
|
|
||||||
- 数据收集的质量依赖主持人水平
|
|
||||||
- 群体思维
|
|
||||||
|
|
||||||
### 在设计流程中
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 设计流程中的高潮,应在进行其他与用户交互较少的调研方法后使用(如自然观察、问卷
|
|
||||||
- 在焦点小组之后,设计师或许需要采访其他的用户 目的是获取更多关于焦点小组中发现的有趣话题的信息
|
|
||||||
|
|
||||||
## **Interviews**
|
|
||||||
|
|
||||||
### 是什么
|
|
||||||
|
|
||||||
目的是深度收集用户信息
|
|
||||||
|
|
||||||
### 如何做
|
|
||||||
|
|
||||||
- 实地、实验室
|
|
||||||
- 足够的隐私程度 以确保用户可以自如地回答问题
|
|
||||||
|
|
||||||
### 数据
|
|
||||||
|
|
||||||
定性>定量
|
|
||||||
|
|
||||||
- **定性**
|
|
||||||
- 设计师所作的一系列访谈笔记
|
|
||||||
- 访谈记录的系统性分析
|
|
||||||
- **定量**
|
|
||||||
- 可以在访谈的开始进行收集
|
|
||||||
- 可以以简短问卷的形式进行(它可以用来迅速获取人种学信息,或者 快速了解用户对于访谈话题的态度,访谈者可以利用这些信息开始访谈环节)
|
|
||||||
|
|
||||||
### 优点
|
|
||||||
|
|
||||||
- 与用户一对一访谈(深度访谈)
|
|
||||||
- 灵活的采访提纲
|
|
||||||
|
|
||||||
### 缺点
|
|
||||||
|
|
||||||
- 需要熟练的采访者
|
|
||||||
> 需要知道用户将会继续说什么,以及 何时控制不再提供价值的对话。 采访者的技能在保持融洽关系方面也很重要, 这种关系应该是既灵活又平衡的。 它使用户舒适, 足以提供诚实的意见 但不能太舒适 而导致用户想用采访者的反应来取悦她。
|
|
||||||
- 数据的收集和分析耗时
|
|
||||||
- 定性数据分析费力
|
|
||||||
|
|
||||||
### 在设计流程中
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 据收集策略达到极点时,访谈最有用。
|
|
||||||
|
|
||||||
- 这意味着当问题得到很好的理解时, 设计人员在需求收集流程中处于关键位置, 需要的是用户最终的澄清或见解。
|
|
||||||
|
|
||||||
## **User Results 用户数据处理**
|
|
||||||
|
|
||||||
> 假设:已对定性和对定量数据进行了适当的分析
|
|
||||||
|
|
||||||
### 描述性统计信息
|
|
||||||
|
|
||||||
**Descriptive statistics**
|
|
||||||
|
|
||||||
描述性统计允许我们总结定量信息 这包括数据集的范围、平均值和中值
|
|
||||||
|
|
||||||
1. 范围
|
|
||||||
2. 平均值
|
|
||||||
3. 中值 (减少极端数据的影响)
|
|
||||||
|
|
||||||
### 用户特征表
|
|
||||||
|
|
||||||
**User characteristics table**
|
|
||||||
|
|
||||||
特征表以简单的形式提供了我们所有数据的快速总结,包括定量数据和定性数据
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 人物画像 Persona
|
|
||||||
|
|
||||||
## **Presenting Task Findings**
|
|
||||||
|
|
||||||
### Scenario
|
|
||||||
|
|
||||||
场景
|
|
||||||
|
|
||||||
> 场景使得我们能**了解用户如何使用系统。**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### 是什么
|
|
||||||
|
|
||||||
场景提供了定性和定量数据的描述。
|
|
||||||
|
|
||||||
#### 作用
|
|
||||||
|
|
||||||
- 使我们有机会传达我们在故事线中 收集数据的丰富性
|
|
||||||
- 故事线会突出所有任务的重要方面以及目前如何完成任务。
|
|
||||||
- 它让任务变的真实,超越了 枯燥的数据图表和表格
|
|
||||||
|
|
||||||
### Essential Case Study
|
|
||||||
|
|
||||||
基本案例场景
|
|
||||||
|
|
||||||
> 帮助理解 **用户的活动以及系统的要求**。
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
#### 三个要素
|
|
||||||
|
|
||||||
**1.用户的目标**
|
|
||||||
|
|
||||||
- 首先,它用户的目标进行命名。 这捕捉到了 X 的哪些方面。
|
|
||||||
- 在本例中 用户可能想知道她去西印度群岛是否需要签证。
|
|
||||||
|
|
||||||
**2. 用户意向**
|
|
||||||
|
|
||||||
- 她进入系统需要进行的一系列步骤。
|
|
||||||
|
|
||||||
**3.系统的责任**
|
|
||||||
|
|
||||||
- 用户完成每个步骤后系统必须执行的操作。
|
|
||||||
- 所以在这里,用户首先要找到 签证要求然后系统请求获得目的地和国籍。 一旦用户提供所需信息 系统将获得相应的签证等信息。
|
|
||||||
|
|
||||||
### Hierarchical Task Analysis
|
|
||||||
|
|
||||||
分层任务分析
|
|
||||||
|
|
||||||
> 最常见的任务分析技术。 使我们考虑**用户当前如何完成任务**。关键点是**可观察的行为**。
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 简单的形式就是一个**大纲**。
|
|
||||||
- 从目标开始。 并对目标中的每个主要步骤进行**编号**。 其中一些步骤包含必须先完成的小步骤 然后才能继续下一步 这项技术是关于用户目标的。
|
|
||||||
- 与基本案例不同。 我们**没有考虑航空公司系统**需要在每个用户步骤中做什么。
|
|
||||||
- 另外请注意, 我没有将一些系统交互任务列入, 比如使用滚动条。 这**只是与用户和完成目标的步骤有关。**
|
|
||||||
|
|
||||||
### Current UI Critique
|
|
||||||
|
|
||||||
当前 UI 评估
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 需要与 UI 进行真实交互。
|
|
||||||
- 系统地分析当前正在使用的界面。 你要确认你明确地传达出需求被满足以及 为了改善用户体验你能做的事情。
|
|
||||||
|
|
||||||
#### 步骤
|
|
||||||
|
|
||||||
**1.确定用户任务**
|
|
||||||
|
|
||||||
对于每个 UI 对应的每个 UI ,你想要确定任务或者用户使用的目的是什么
|
|
||||||
|
|
||||||
**2. 测定任务完成时间**
|
|
||||||
|
|
||||||
要客观的测定所需时间去 响应这个客户提交的任务
|
|
||||||
|
|
||||||
在这个例子中 我选择了一些点击,它会让我使用这个应用程序,或者网站,或者通过终端完成任务。
|
|
||||||
|
|
||||||
**3. 评估操作**
|
|
||||||
|
|
||||||
**4. 改进方法**
|
|
||||||
|
|
||||||
## **相关资源**
|
|
||||||
|
|
||||||
Resources for Requirement Gathering
|
|
||||||
|
|
||||||
1. [25 Useful Brainstorming Techniques](http://personalexcellence.co/blog/brainstorming-techniques/)
|
|
||||||
2. [Non-Functional Requirements - Minimal Checklist](http://leadinganswers.typepad.com/leading_answers/2009/03/nonfunctional-requirements-minimal-checklist.html)
|
|
||||||
3. [Differentiating between Functional and Nonfunctional Requirements](http://searchsoftwarequality.techtarget.com/answer/Differentiating-between-Functional-and-Nonfunctional-Requirements)
|
|
||||||
4. [Facilitated Brainstorming](http://www.usabilityfirst.com/usability-methods/facilitated-brainstorming/)
|
|
||||||
5. [5 powerful ways to brainstorming with teams/](http://blog.abovethefolddesign.com/2010/11/11/5-powerful-ways-to-brainstorming-with-teams/)
|
|
||||||
6. [ips for Structuring Better Brainstorming Sessions](http://www.inspireux.com/2013/07/18/tips-for-structuring-better-brainstorming-sessions/)
|
|
||||||
7. [Collaborative Brainstorming for Better UX Workshop](http://www.slideshare.net/jessicaivins/aiga-cincy-uxworkshop01)
|
|
||||||
8. [WHAT IS AN AFFINITY DIAGRAM?](http://asq.org/learn-about-quality/idea-creation-tools/overview/affinity.html)
|
|
||||||
9. [Affinity Diagrams](https://www.mindtools.com/pages/article/newTMC_86.htm)
|
|
||||||
10. [Affinity diagramming](http://infodesign.com.au/usabilityresources/affinitydiagramming/)
|
|
|
@ -1,111 +0,0 @@
|
||||||
---
|
|
||||||
title: Design Alternatives
|
|
||||||
summary: Introduction to User Experience Design|Week3
|
|
||||||
created: 2021-11-14T11:18:45+08:00
|
|
||||||
categories:
|
|
||||||
- UX学习笔记
|
|
||||||
- Introduction to User Experience Design
|
|
||||||
tags:
|
|
||||||
- UX
|
|
||||||
lastmod: 2022-04-16T12:56:27.924Z
|
|
||||||
---
|
|
||||||
|
|
||||||
## Review of Design Goals 审查设计目标
|
|
||||||
|
|
||||||
### 用户体验的核心目标
|
|
||||||
|
|
||||||
> "用户使用界面来完成任务 "
|
|
||||||
>
|
|
||||||
> 通过理解用户以及他们要完成的任务 以便设计出最好的界面(interface)
|
|
||||||
|
|
||||||
前提是,最好的界面 只能在我们了解用户和他们想要完成的任务之后才能被设计出
|
|
||||||
|
|
||||||
### 设计的定义
|
|
||||||
|
|
||||||
> 一种创新的开发用来满足一些需求。
|
|
||||||
|
|
||||||
### 设计的目标
|
|
||||||
|
|
||||||
- 要比现有的设计更好地满足用户的需要
|
|
||||||
- 不是为了新奇本身,而是为了服务和改善用户体验
|
|
||||||
- 设计新的界面是为了**找到更好的方法来调解用户如何实现任务**。 它可能需要我们创建一个全新的系统。 或者,我们可以简单地设计出新的输入和输出。
|
|
||||||
|
|
||||||
### 设计时,需考虑的三个方面
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- **个人层面 individual**
|
|
||||||
- 考虑用户特征。 这些包括用户的年龄,教育水平,和对科技的适应程度,
|
|
||||||
- 考虑用户之间的差异。
|
|
||||||
- **群体 group**
|
|
||||||
- 考虑用户之间的交互(一组用户)
|
|
||||||
- **社会 society**
|
|
||||||
- 文化事件会影响系统的使用 和采纳情况。
|
|
||||||
- 我们需要了解与用户所从事的任务相关的文化价值观, 并在设计时考虑这些问题
|
|
||||||
|
|
||||||
## **Design Alternatives 设计替代方案**
|
|
||||||
|
|
||||||
### 目标
|
|
||||||
|
|
||||||
开发一个比现在更能满足用户需求的界面(基于设计的问题空间)
|
|
||||||
|
|
||||||
### 关键
|
|
||||||
|
|
||||||
使用屏幕实践将设计基础概念化
|
|
||||||
|
|
||||||
### Road map 路线
|
|
||||||
|
|
||||||
- **能用 useful**
|
|
||||||
|
|
||||||
- **目标**
|
|
||||||
|
|
||||||
改善用户完成目标任务的能力
|
|
||||||
|
|
||||||
- **方法**
|
|
||||||
|
|
||||||
回顾第一阶段获得的数据 并且鉴别出用户的需求
|
|
||||||
|
|
||||||
1. **显性需求**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
2. **隐形需求**
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- **好用 usable**
|
|
||||||
|
|
||||||
- **目标**
|
|
||||||
|
|
||||||
以功能性和在第一阶段所发现的非功能性的需求为基础,使用户更加有效高效和满意 地完成任务,从而改善他们的用户体验
|
|
||||||
|
|
||||||
- **方法**
|
|
||||||
|
|
||||||
回顾第一阶段的数据,确定设计可替代品中功能性和非功能性的需求
|
|
||||||

|
|
||||||
|
|
||||||
1. **功能性需求**
|
|
||||||
|
|
||||||
——面向用户的
|
|
||||||
|
|
||||||
系统应该完成的,这些基于用户所期望的系统功能
|
|
||||||
|
|
||||||
2. **非功能性需求**
|
|
||||||
|
|
||||||
——面向商家的
|
|
||||||
|
|
||||||
和系统开发有关的限制。它们也可以被看作质量特性( 这些特性包含了许多或后端功能,比如安全性,可执行性,可维护性 但是他们也包括了前端功能货可用特性,像布局、流程或者甚至是语言本地化需求)
|
|
||||||
|
|
||||||
- **小组讨论**
|
|
||||||
- 头脑风暴
|
|
||||||
- 学生或设计师的个人特征, 也会影响到他们发现的需求
|
|
||||||
- 在头脑风暴中,最重要的原则是打开思路,不要错过任何点子
|
|
||||||
- 想法整理
|
|
||||||
使用类同图表有助于把头脑风暴数据设计成流线型
|
|
||||||
1. 参与者是设计师或与设计师相关的人
|
|
||||||
2. 在各自的便贴纸上写下想法。
|
|
||||||
3. 然后设计师收起这些纸条
|
|
||||||
4. 并把他们按照相同程度组织起来,以一些典型的概念为导向。
|
|
||||||
5. 之后设计师们来决定什么样的界面 可以满足所有的功能性的需求 一类或者一个同类的需求
|
|
||||||
- **界面类型**
|
|
||||||

|
|
|
@ -1,130 +0,0 @@
|
||||||
---
|
|
||||||
title: Prototyping
|
|
||||||
summary: Introduction to User Experience Design|Week4
|
|
||||||
created: 2021-11-18T21:26:41+08:00
|
|
||||||
categories:
|
|
||||||
- UX学习笔记
|
|
||||||
- Introduction to User Experience Design
|
|
||||||
tags:
|
|
||||||
- UX
|
|
||||||
---
|
|
||||||
|
|
||||||
## **关于 Prototyping**
|
|
||||||
|
|
||||||
### 什么是原型开发
|
|
||||||
|
|
||||||
- 原型开发可以被定义为一个新颖设计的早期模型
|
|
||||||
- 通过原型来评估新设计的各个方面 并检查设计是否达到了预期的结果
|
|
||||||
|
|
||||||
### 原型开发的作用
|
|
||||||
|
|
||||||
- 经济(节约时间的金钱)
|
|
||||||
- 快速构建、迭代
|
|
||||||
|
|
||||||
### 水平原型
|
|
||||||
|
|
||||||

|
|
||||||
涵盖功能的广度,整合所含的功能(大概有什么)
|
|
||||||
|
|
||||||
### 垂直原型
|
|
||||||
|
|
||||||

|
|
||||||
对一些特征进行深入的建模(多层级)
|
|
||||||
|
|
||||||
## **低保真 Lofi Prototype**
|
|
||||||
|
|
||||||
### 低保真和高保真的区别
|
|
||||||
|
|
||||||
- 低保真原型与最终设计几乎没有什么相似之处,无论是在形式或功能上(快速迭代、验证想法)
|
|
||||||
- 高保真原型则与最终设计非常相似
|
|
||||||
|
|
||||||
### 注意事项
|
|
||||||
|
|
||||||
- 注重用户反馈
|
|
||||||
- 也可以让利益相关者加入反馈过程
|
|
||||||
- 避免完美主义,注重想法的表达和验证,关注核心路径
|
|
||||||
|
|
||||||
### 三种形式
|
|
||||||
|
|
||||||
#### 1. 草图
|
|
||||||
|
|
||||||
表明用户场景,痛点是怎么产生的(场景)
|
|
||||||

|
|
||||||
|
|
||||||
#### 2. 故事版
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 一种以静态方式提供叙事的常用方法
|
|
||||||
- 将设计放在上下文中,来考虑用户如何在给定的场景中使用我们的新设计。
|
|
||||||
- 场景互动的迭代,简单的任务图形、场景互动
|
|
||||||
|
|
||||||
#### 3.卡片原型
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 表示我们与实际界面可能发生的交互序列。
|
|
||||||
- 使用一组索引卡。逐一代表一个用户在尝试完成任务时,会遇到的一序列屏幕。
|
|
||||||
|
|
||||||
## **其他原型方式**
|
|
||||||
|
|
||||||
### 绿野仙踪/奥茨法师
|
|
||||||
|
|
||||||
_Wizard of Oz_
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 用来模拟产品的功能。
|
|
||||||
- 通过让人执行通常由计算机执行的任务,在这里用户不知道该产品是不具备功能性的
|
|
||||||
- 优点:能够节省建立功能性产品的时间和金钱
|
|
||||||
- 缺点:
|
|
||||||
- 需要相当长的时间来使其正常运转,并且它总是需要多人操作
|
|
||||||
- 需要一个训练有素的巫师,最终用户可能对系统有不切实际的期望。
|
|
||||||
- 基于欺骗性的功能,反过来可能会限制他们提供反馈,继而限制从收集的数据中得出的推论
|
|
||||||
|
|
||||||
### 概念验证视频
|
|
||||||
|
|
||||||
_Proof of Concept Video_
|
|
||||||
|
|
||||||
- 一个能够在各种场景下展示各种用途和系统的功能的视频(系统是如何工作的 以及在什么情况下它会有用)
|
|
||||||
|
|
||||||
### 隐喻技术
|
|
||||||
|
|
||||||
_Metaphor Development_
|
|
||||||
|
|
||||||
- 考虑用户如何看待设计
|
|
||||||
- 帮助用户建立新设计如何运作的**相关心理模型**
|
|
||||||
- 隐喻将新功能与用户以及熟悉的系统功能相比较对比。
|
|
||||||
|
|
||||||
## **相关资源**
|
|
||||||
|
|
||||||
### Resources and Tools for Protoyping 1
|
|
||||||
|
|
||||||
1. [prototyping.html](http://www.usability.gov/how-to-and-tools/methods/prototyping.html)
|
|
||||||
2. [high fidelity prototype/](http://www.usabilityfirst.com/glossary/high-fidelity-prototype/)
|
|
||||||
3. [high fidelity vs low fidelity prototyping web design and app development](http://www.atlargeinc.com/insights/high-fidelity-vs-low-fidelity-prototyping-web-design-and-app-development)
|
|
||||||
4. [Social Mirror](https://www.youtube.com/watch?v=91-JnTq3MhA)
|
|
||||||
|
|
||||||
### Tools
|
|
||||||
|
|
||||||
1. [Uxrecorder](http://www.uxrecorder.com/)
|
|
||||||
2. [Invision](https://www.invisionapp.com/)
|
|
||||||
3. [Marvel](https://marvelapp.com/)
|
|
||||||
4. [Axure](http://www.axure.com/)
|
|
||||||
|
|
||||||
### Resources for Prototyping 2
|
|
||||||
|
|
||||||
1. [What a prototype is and is not](https://uxmag.com/articles/what-a-prototype-is-and-is-not)
|
|
||||||
2. [the skeptics guide to low fidelity prototyping](https://www.smashingmagazine.com/2014/10/the-skeptics-guide-to-low-fidelity-prototyping/)
|
|
||||||
3. [low fidelity prototype](http://www.usabilityfirst.com/glossary/low-fidelity-prototype/)
|
|
||||||
4. [why every consumer internet startup should do more low fidelity prototyping](http://andrewchen.co/why-every-consumer-internet-startup-should-do-more-low-fidelity-prototyping/)
|
|
||||||
5. [lofi vs hifi prototyping how real does the real thing have to be](http://www.telono.com/en/articles/lo-fi-vs-hi-fi-prototyping-how-real-does-the-real-thing-have-to-be/)
|
|
||||||
6. [prototyping types of prototypes](http://it.toolbox.com/blogs/enterprise-solutions/prototyping-types-of-prototypes-14927)
|
|
||||||
7. [horizontal and vertical prototypes](http://www.usabilityfirst.com/glossary/horizontal-and-vertical-prototypes/)
|
|
||||||
8. [introduction sketch ui design/](http://marketblog.envato.com/grow-improve/creativity/introduction-sketch-ui-design/)
|
|
||||||
9. [the messy art of ux sketching/](https://www.smashingmagazine.com/2011/12/the-messy-art-of-ux-sketching/)
|
|
||||||
10. [how to draw quick useful ui sketches](http://www.slideshare.net/LaneHalley/how-to-draw-quick-useful-ui-sketches)
|
|
||||||
11. [User interface sketching tips part-1](http://ui-patterns.com/blog/User-interface-sketching-tips-part-1)
|
|
||||||
12. [storyboarding in the software design process](https://uxmag.com/articles/storyboarding-in-the-software-design-process)
|
|
||||||
13. [the 8 steps to creating a great storyboard](http://www.fastcodesign.com/1672917/the-8-steps-to-creating-a-great-storyboard)
|
|
||||||
14. [users story ux storyboarding](http://www.slideshare.net/fgarofalo/users-story-ux-storyboarding)
|
|
|
@ -1,94 +0,0 @@
|
||||||
---
|
|
||||||
title: Evaluation
|
|
||||||
summary: Introduction to User Experience Design|Week5
|
|
||||||
created: 2021-11-18T22:09:49+08:00
|
|
||||||
categories:
|
|
||||||
- UX学习笔记
|
|
||||||
- Introduction to User Experience Design
|
|
||||||
tags:
|
|
||||||
- UX
|
|
||||||
---
|
|
||||||
|
|
||||||
## **评估**
|
|
||||||
|
|
||||||
- 可以确定我们正在改善用户的体验
|
|
||||||
- 需要定性、定量的数据
|
|
||||||
|
|
||||||
## **分类**
|
|
||||||
|
|
||||||
### 形成性评估
|
|
||||||
|
|
||||||
- 在设计**低保真**原型的过程中进行的
|
|
||||||
- 数据:( 例如:完成任务的时间或点击次数)(关注任务)
|
|
||||||
- 环境:一个受控环境, 例如, 实验室或办公室
|
|
||||||
|
|
||||||
### 总结性评估
|
|
||||||
|
|
||||||
- 是在**高保真**原型或最终界面即将完成的情况下进行的。
|
|
||||||
- 数据:设计者能够访问的和分析的数据, 它们可以告诉我们如何使用系统。 例如,用户开始和结束会话时可能会有时间戳, 并记录用户如何与系统交互的数据(真实场景)、
|
|
||||||
- 场景:高保真原型可在野外进行,如真实的使用场景
|
|
||||||
|
|
||||||
## **如何评估**
|
|
||||||
|
|
||||||
### 数据收集
|
|
||||||
|
|
||||||
- 以问卷形式进行的定量数据,
|
|
||||||
- 记录用户完成任务时所经过的路径的数据。
|
|
||||||
- 用户访谈的形式获得的定性数据
|
|
||||||
|
|
||||||
### 衡量
|
|
||||||
|
|
||||||
- 衡量任务的目标所达到的程度(完成程度)
|
|
||||||
- 包括完成任务的时间、单击次数或 执行任务时出现的错误数。
|
|
||||||
|
|
||||||
### 可学习性
|
|
||||||
|
|
||||||
- 定义:首次成功完成任务的简单程度。
|
|
||||||
- 衡量:完成任务的点击次数、完成任务所需的时间量来获得客观的测量结果, 然后将这些数据与专家的表现进行比较。
|
|
||||||
|
|
||||||
### 可记忆性
|
|
||||||
|
|
||||||
- 定义:要记住产品用方法的难易程度(如何在反复试验之后在界面上执行给定的任务)
|
|
||||||
- 衡量:时间量或点击次数(完成一项反复试验的任务, 以获得可记忆性的测量)
|
|
||||||
|
|
||||||
### 主观情感评估
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
- 认知测量:心理负担
|
|
||||||
- 情感测量:情感体验
|
|
||||||
|
|
||||||
## **相关资源**
|
|
||||||
|
|
||||||
1. [usability evaluation](http://www.usability.gov/what-and-why/usability-evaluation.html)
|
|
||||||
2. [15. Usability Evaluation](https://www.interaction-design.org/literature/book/the-encyclopedia-of-human-computer-interaction-2nd-ed/usability-evaluation)
|
|
||||||
3. [more than ease of use](http://www.wqusability.com/articles/more-than-ease-of-use.html)
|
|
||||||
4. [Measuring Usability: Are Effectiveness, Efficiency, and Satisfaction Really Correlated?](http://www.diku.dk/~kash/papers/CHI2000_froekjaer.pdf)
|
|
||||||
5. [usability 101|introduction to usability/](https://www.nngroup.com/articles/usability-101-introduction-to-usability/)
|
|
||||||
|
|
||||||
## **推荐教材**
|
|
||||||
|
|
||||||
### Trade Book
|
|
||||||
|
|
||||||
- **The Design of Everyday Things**
|
|
||||||
2013 edition by Don Norman
|
|
||||||
|
|
||||||
### Text Books
|
|
||||||
|
|
||||||
- **Interaction Design**
|
|
||||||
- by Jennifer Preece, Helen Sharp and Yvonne Rogers (in alphabetical order).
|
|
||||||
- There are four editions of this book. I believe any of the editions are a good purchase. This is the book I use in my undergraduate college course.
|
|
||||||
- **Human Computer Interaction**
|
|
||||||
- 2004 by Dix, Finlay, Abowd & Beale.
|
|
||||||
- This is an advance text book.
|
|
||||||
- **Understanding Your Users**
|
|
||||||
- 2015 edition by Baxter, Courage & Caine.
|
|
||||||
- I really like this book because it does what it claims, provides a "practical guide to User Research Methods
|
|
||||||
|
|
||||||
## **参考网站**
|
|
||||||
|
|
||||||
- [What is Usability? | Usability Body of Knowledge](http://www.usabilitybok.org/what-is-usability)
|
|
||||||
- [User interface design - Wikipedia](https://en.wikipedia.org/wiki/User_interface_design)
|
|
||||||
- [User experience design - Wikipedia](https://en.wikipedia.org/wiki/User_experience_design)
|
|
||||||
- [Usability First: Usability in Website and Software Design](http://www.usabilityfirst.com/)
|
|
||||||
- [Methods](http://www.usability.gov/how-to-and-tools/methods/index.html)
|
|
File diff suppressed because one or more lines are too long
|
@ -1,77 +0,0 @@
|
||||||
---
|
|
||||||
title: SQL · 在 Windows 10 上安装 sqlite
|
|
||||||
created: 2022-05-23
|
|
||||||
summary: 写给计算机小白的 sqlite 安装笔记
|
|
||||||
tags:
|
|
||||||
- SQL
|
|
||||||
---
|
|
||||||
|
|
||||||
参考: [Site Unreachable](https://www.runoob.com/sqlite/sqlite-installation.html)
|
|
||||||
|
|
||||||
## 1. 下载二进制文件
|
|
||||||
|
|
||||||
- 请访问 [SQLite 下载页面](http://www.sqlite.org/download.html),从 Windows 区下载预编译的二进制文件。
|
|
||||||
- 您需要下载 **sqlite-tools-win32-\*.zip** 和 **sqlite-dll-win32-\*.zip** 压缩文件。
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
## 2. 创建安装文件夹
|
|
||||||
|
|
||||||
- 在 C 盘内创建文件夹 sqlite(在别的地方应该也可以?),并在此文件夹下解压上面两个压缩文件,将得到 sqlite3.def、sqlite3.dll 和 sqlite3.exe 文件。如:
|
|
||||||

|
|
||||||
|
|
||||||
## 3. 添加环境变量
|
|
||||||
|
|
||||||
参考:[sqlite 在 windows 下载安装,配置环境变量](https://blog.csdn.net/gymaisyl/article/details/108073278)
|
|
||||||
|
|
||||||
首先,打开控制面板,如果找不到的话,直接搜索,例如:
|
|
||||||

|
|
||||||
|
|
||||||
然后点击**系统与安全**,再点击 **系统**
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
在新窗口中点击**高级系统设置** -> **环境变量**
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
如上图所示,在蓝色区域新建一个环境变量,此处填写一开始创建 sqlite 文件的路径,比如这里就是`C:\sqlite`
|
|
||||||
|
|
||||||
## 4. 命令提示符中查看 sqlite3 版本
|
|
||||||
|
|
||||||
**什么是命令提示符?**
|
|
||||||
|
|
||||||
> 命令提示符是大多数 Windows [操作系统中](https://zhcn.eyewated.com/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F/)可用的[命令行解释器](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AF%E5%91%BD%E4%BB%A4%E8%A1%8C%E8%A7%A3%E9%87%8A%E5%99%A8%EF%BC%9F/)应用程序。
|
|
||||||
>
|
|
||||||
> 命令提示符用于执行输入的[命令](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AF%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%91%BD%E4%BB%A4%EF%BC%9F/) 。 大多数这些命令用于通过脚本和[批处理文件](https://zhcn.eyewated.com/%E4%BB%80%E4%B9%88%E6%98%AFbat%E6%96%87%E4%BB%B6%EF%BC%9F/)自动执行任务,执行高级管理功能以及排除和解决某些类型的 Windows 问题。
|
|
||||||
>
|
|
||||||
> 命令提示符被正式称为*Windows 命令处理器,*但有时也被称为*命令外壳程序*或*cmd 提示符* ,甚至称其为文件名*cmd.exe* 。
|
|
||||||
> ——[命令提示符(它是什么以及如何使用它)](https://zhcn.eyewated.com/%E5%91%BD%E4%BB%A4%E6%8F%90%E7%A4%BA%E7%AC%A6%EF%BC%9A%E5%AE%83%E6%98%AF%E4%BB%80%E4%B9%88%E4%BB%A5%E5%8F%8A%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%AE%83/)
|
|
||||||
|
|
||||||
我的理解就是用代码的方式操作电脑系统
|
|
||||||
|
|
||||||
**如何打开命令提示符:**
|
|
||||||

|
|
||||||
|
|
||||||
打开后输入`sqlite3` ,出现下面的文字就是安装成功了
|
|
||||||

|
|
||||||
|
|
||||||
## 常用命令行
|
|
||||||
|
|
||||||
- 需要在文件夹里运行
|
|
||||||
- `cd` 的时候按 tab 可以自动填充文件名 (VS Code 里面按 command)
|
|
||||||
|
|
||||||
| 命令 | 功能 |
|
|
||||||
| ---------------------- | ------------------------------------------------------------------------------------------- |
|
|
||||||
| `ls`(win 用 `dir`) | 展示当前文件夹文件 |
|
|
||||||
| `cd` | 改变当前文件夹(change directory) 按 tab 可以自动填充 |
|
|
||||||
| `cd..` | 去到上个层级的文件夹 |
|
|
||||||
| `clear` | 清除命令行记录 |
|
|
||||||
| `mkdir` | 创建新文件夹(make directory) |
|
|
||||||
| `touch`(win 用 `edit`) | 创建新文件(可以一次性创建多个) |
|
|
||||||
| `mv` | 移动文件,第一个参数是要移动的文件,第二个是目的地,如 `mv index.html ../` 为移动到上一层级 |
|
|
||||||
| `rmdir` | 删除空文件夹(remove directory) |
|
|
||||||
| `rm -R` | 删除文件夹(R-recursively) |
|
|
||||||
| `pwd` | 当前所在位置 |
|
|
||||||
| `rm`(win 用 `del`) | 删除文件 |
|
|
|
@ -1,133 +0,0 @@
|
||||||
---
|
|
||||||
title: Hypothesis 使用小记
|
|
||||||
created: 2022-05-25
|
|
||||||
summary: Hypothesis同步到Obsidian / Logseq的方法
|
|
||||||
tags:
|
|
||||||
- Logseq
|
|
||||||
- Obsidian
|
|
||||||
---
|
|
||||||
|
|
||||||
Hypothesis 太好用了,方便我满世界乱画写屁话(?),用它在网页上高亮,就像用荧光笔在纸上标注一样轻松 ,写标注就写在 3M 便利贴上,哪里都好贴,而且还支持用 Markdown 写,真的越用越顺手
|
|
||||||
|
|
||||||
它导出的笔记提供了导出的 API,可以轻松同步到 Obsidian / Logseq,真是平易近人呢!
|
|
||||||
|
|
||||||
我的使用例子:
|
|
||||||
|
|
||||||
我在 Obsidian 中导出的笔记:
|
|
||||||

|
|
||||||
|
|
||||||
一些基础的部分我会省略掉,详情可以看这篇文章:[开源、可定制的网页批注工具——Hypothesis](https://type.cyhsu.xyz/2020/10/hypothesis-tutorial/)
|
|
||||||
|
|
||||||
在下面这些操作之前,需要先注册一个 Hypotheis 账号,并安装浏览器扩展:
|
|
||||||
|
|
||||||
- 注册:[Get started.](https://web.hypothes.is/start/#)
|
|
||||||
- Chrome 扩展:[Hypothesis - Web & PDF Annotation](https://chrome.google.com/webstore/detail/hypothesis-web-pdf-annota/bjfhmglciegochdpefhhlphglcehbmek)
|
|
||||||
然后在浏览器扩展中登陆。
|
|
||||||
|
|
||||||
## 同步到 Logseq
|
|
||||||
|
|
||||||
Logseq 我用得不多,如果有写错的,欢迎给我提建议~
|
|
||||||
|
|
||||||
### 1. 打开插件系统开关
|
|
||||||
|
|
||||||
(如果打开了可以省略这个)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
如果在国内连接插件市场,最好设置一下代理,不然可能装不上,具体的设置需要看一下 VPN 端口号之类的。
|
|
||||||
|
|
||||||
### 2. 安装 Hypothesis 插件
|
|
||||||
|
|
||||||
打开 Logseq 的插件市场,找到如下名为
|
|
||||||
**Hypothesis**的插件:
|
|
||||||

|
|
||||||
如果一直下载不了的话,可以直接在 Github 下载:[logseq-hypothesis](https://github.com/c6p/logseq-hypothesis)
|
|
||||||
|
|
||||||
然后在这里导入:
|
|
||||||

|
|
||||||
|
|
||||||
### 3. 获取 API Token
|
|
||||||
|
|
||||||
在这里生成一个 API Token:[Regenerate your API token](https://hypothes.is/account/developer)
|
|
||||||
|
|
||||||
复制后点击 Logseq 右上角的这个 H 的标志:
|
|
||||||

|
|
||||||
|
|
||||||
然后填入刚刚复制的 API Token 和用户名
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
用户名跟 Hypothesis 这里显示的一样,比如我的就是 Sevicheeee
|
|
||||||

|
|
||||||
|
|
||||||
### 4. 同步笔记
|
|
||||||
|
|
||||||
点击 `Fetch Latest Notes` 会拉取最新的笔记
|
|
||||||
|
|
||||||
如果选择了指定页面,然后点`Add page notes to graph`,会自动生成一篇相应的笔记,比如:
|
|
||||||

|
|
||||||
|
|
||||||
### 5. 修改笔记模板
|
|
||||||
|
|
||||||
如果想修改笔记模板的话,可以在`setting`中修改:
|
|
||||||

|
|
||||||
|
|
||||||
## 同步到 Obsidian
|
|
||||||
|
|
||||||
### 1. 安装 Hypothesis 插件
|
|
||||||
|
|
||||||
如图所示:
|
|
||||||

|
|
||||||
|
|
||||||
Github: [obsidian-hypothesis-plugin](https://github.com/weichenw/obsidian-hypothesis-plugin)
|
|
||||||
|
|
||||||
### 2. API 配置
|
|
||||||
|
|
||||||
打开插件设置,点击右上角的`Connect`, 输入你的 API Token 并保存,如果没有获取的话,请在这里获取:[Regenerate your API token](https://hypothes.is/account/developer)
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
可以在这里选择笔记保存的位置:
|
|
||||||

|
|
||||||
|
|
||||||
其中`Use Domain Folders` 是按域名来划分文件结构,如果没有打开的话就是默认一篇笔记一个 md 文档,如下图红框所示就是打开了这个,下面蓝色的就是没打开时的输出结构
|
|
||||||

|
|
||||||
|
|
||||||
### 3. 笔记模板配置
|
|
||||||
|
|
||||||
可以在右边的文本框内设置笔记输出格式
|
|
||||||

|
|
||||||
说实话,我没有怎么看懂 Orz, 然后这是我的模板:
|
|
||||||
|
|
||||||
```js
|
|
||||||
{% if is_new_article %}# {{title}}
|
|
||||||
|
|
||||||
## Metadata
|
|
||||||
{% if author %}- Author: [{{author}}]({{authorUrl}}){% endif %}
|
|
||||||
- Title: {{title}}
|
|
||||||
{% if url %}- Reference: {{url}}{% endif %}
|
|
||||||
- Category: #source/article🗞{% endif %}
|
|
||||||
- Tags:
|
|
||||||
|
|
||||||
{% if is_new_article -%}## Highlights{%- endif %}
|
|
||||||
{% for highlight in highlights -%}- {{highlight.text}}
|
|
||||||
{% if highlight.tags | length %} - Tags: {% for tag in highlight.tags -%}#{{tag| replace(" ", "-")}} {%- endfor %}{%- endif %}
|
|
||||||
{% if highlight.annotation %} - Annotation: {{highlight.annotation}}{%- endif -%}{%- endfor -%}
|
|
||||||
```
|
|
||||||
|
|
||||||
效果:
|
|
||||||

|
|
||||||
|
|
||||||
### 4. 更新笔记
|
|
||||||
|
|
||||||
点击右边这个标志就可以更新笔记了~也可以在设置里打开启动时自动抓取的设置
|
|
||||||

|
|
||||||
|
|
||||||
## 订阅 Hypothesis 的 RSS
|
|
||||||
|
|
||||||
- 文档:[Atom & RSS Feeds for Annotations](https://web.hypothes.is/help/atom-rss-feeds-for-annotations/)
|
|
||||||
- 工具:[Subscribe to Hypothesis web annotations](https://diegodlh.github.io/hfeed/)
|
|
||||||
|
|
||||||
## 其他参考
|
|
||||||
|
|
||||||
- [我的 Obsidian 使用经验 - 程序员的喵](https://catcoding.me/p/obsidian-for-programmer/)
|
|
|
@ -1,166 +0,0 @@
|
||||||
---
|
|
||||||
title: VPS · Jellyfin结合Cloudreve开启线上影院
|
|
||||||
created: 2022-06-15
|
|
||||||
summary: 基于 Docker 和 Nginx 的信心搭建过程
|
|
||||||
image: /2022-06-15-jellyfin/1.jpg
|
|
||||||
tags:
|
|
||||||
- Nginx
|
|
||||||
- VPS
|
|
||||||
- Docker
|
|
||||||
---
|
|
||||||
|
|
||||||
昨天搭了一下 Pleroma,完全失败,完全没信心了,所以今天决定随便在[Awesome Self Hosted | LibHunt](https://selfhosted.libhunt.com/)找了一个排名很靠前的东西搭一下,给自己建立一点没有必要的信心……
|
|
||||||
|
|
||||||
刚好最近朋友找电影资源很犯难,所以我决定拿排在 Media 第一的[Jellyfin](https://jellyfin.org/)试试手。
|
|
||||||
|
|
||||||
## 关于 Jellyfin
|
|
||||||
|
|
||||||
Jellyfin 是一个在线的流媒体影音库,对电影、音乐、有声书都有比较好的支持。除了在 web 端观看之外,它还支持很多的[客户端](https://jellyfin.org/clients/),几乎是随处可用,目前我只试过安卓端的,其功能与网页端无异,适配得很好,体验流畅。
|
|
||||||
|
|
||||||
可以在这里试一下 Demo:[Jellyfin](https://demo.jellyfin.org/stable/web/index.html)
|
|
||||||
|
|
||||||
(用户名 demo,密码留空)
|
|
||||||
|
|
||||||
下面是我的成果:-D
|
|
||||||

|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
||其实我也是搭完才知道它有什么功能的||
|
|
||||||
|
|
||||||
## Cloudrever
|
|
||||||
|
|
||||||
Jellyfin 目前不支持 S3 存储,所以我需要一个网盘来存储和管理 VPS 上的媒体资源。看了塔塔的 [音乐库搭建 ](https://mantyke.icu/2022/cloudreve-navidrome/) 文章后我决定试一下 [Cloudreve](https://cloudreve.org/) ,具体的搭建过程这里按下不表,是完全照着塔塔的教程和 [Cloudreve 文档](https://docs.cloudreve.org/getting-started/install) 做的
|
|
||||||
|
|
||||||
### 反代
|
|
||||||
|
|
||||||
需要注意的是,配置 Nginx 反代时,与往常不同,需要设置一下最大的文件大小,以免后期上传失败:
|
|
||||||
|
|
||||||
```bash title="/etc/nginx/conf.d/jellyfin.conf" {7}
|
|
||||||
location / {
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header Host $http_host;
|
|
||||||
proxy_redirect off;
|
|
||||||
proxy_pass http://127.0.0.1:5212;
|
|
||||||
|
|
||||||
# 如果您要使用本地存储策略,请将下一行注释符删除,并更改大小为理论最大文件尺寸
|
|
||||||
client_max_body_size 20000m;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### 一些配置
|
|
||||||
|
|
||||||
1. **最大容量**
|
|
||||||
|
|
||||||
在 `管理面板-> 用户组` 里可修改
|
|
||||||

|
|
||||||
|
|
||||||
2. **配置离线下载**
|
|
||||||
|
|
||||||
配置好离线下载就可以用它在后台下载种子资源了。
|
|
||||||
如果用的是 docker-compose 来安装,下面的应该这样配置:
|
|
||||||

|
|
||||||
|
|
||||||
- **[不可修改]** RPC 服务器地址 => `http://aria2:6800`
|
|
||||||
- **[可修改, 需保持和 docker-compose.yml 文件一致]** RPC 授权令牌 => `your_aria_rpc_token`
|
|
||||||
- **[不可修改]** Aria2 用作临时下载目录的 节点上的绝对路径 => `/data`
|
|
||||||
|
|
||||||
最后在 cloudreve 面板里创建一个用来存放 jelly 用的文件夹,比如 `jellyfin`
|
|
||||||
|
|
||||||
## Jellyfin
|
|
||||||
|
|
||||||
### 搭建
|
|
||||||
|
|
||||||
jellyfin 的搭建非常简单,给了我做人的很大信心(没有),我这里依旧选择用 docker-compose 来搭建。
|
|
||||||
|
|
||||||
官方文档:[Installing Jellyfin | Documentation - Jellyfin Project](https://jellyfin.org/docs/general/administration/installing.html#docker)
|
|
||||||
|
|
||||||
首先创建一个配置文件夹并进入:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo mkdir /opt/jellyfin && cd /opt/jellyfin
|
|
||||||
```
|
|
||||||
|
|
||||||
创建配置文件
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nano docker-compose.yml
|
|
||||||
```
|
|
||||||
|
|
||||||
写入:
|
|
||||||
|
|
||||||
```yaml title="docker-compose.yml" {10-11}
|
|
||||||
version: '3.5'
|
|
||||||
services:
|
|
||||||
jellyfin:
|
|
||||||
image: jellyfin/jellyfin
|
|
||||||
container_name: jellyfin
|
|
||||||
user: root
|
|
||||||
network_mode: 'host'
|
|
||||||
volumes:
|
|
||||||
- /path/to/config:/config
|
|
||||||
- /path/to/cache:/cache
|
|
||||||
- /path/to/media:/media #修改为cloudreve的文件夹
|
|
||||||
- /path/to/media2:/media2:ro #修改为cloudreve的文件夹
|
|
||||||
restart: 'unless-stopped'
|
|
||||||
# Optional - alternative address used for autodiscovery
|
|
||||||
environment:
|
|
||||||
- JELLYFIN_PublishedServerUrl=http://你的域名
|
|
||||||
```
|
|
||||||
|
|
||||||
其中需要修改 `/path/to/media:/media` 的前半部分为 cloudreve 中在 VPS 中的存储路径,比如改为`/opt/drive/cloudreve/uploads/` ,如果有多个 cloudreve 用户则可以在后面加用户 id,比如 `/opt/drive/cloudreve/uploads/1` 这样
|
|
||||||
|
|
||||||
然后`/path/to/media2` 也是同样的修改,改为 `/opt/drive/cloudreve/uploads/`
|
|
||||||
|
|
||||||
改完域名之后,执行 `sudo docker-compose up -d` 就可以在端口 `你的ip:8096` 看到界面了。
|
|
||||||
|
|
||||||
### 反代
|
|
||||||
|
|
||||||
我用的是 Nginx 来进行反代,虽然每次都是一样的操作,但是直接写可以复制粘贴会比较简单,所以我现在准备说废话。
|
|
||||||
|
|
||||||
首先,创建配置文件:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nano /etc/nginx/conf.d/jellyfin.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
写入:
|
|
||||||
|
|
||||||
```bash title="/etc/nginx/conf.d/jellyfin.conf" {2,4}
|
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name 你的域名;
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8096;
|
|
||||||
proxy_set_header HOST $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
SSL/TLS 配置可以看我之前这篇:[配置 Cloudflare 的免费 SSL 证书](2022-06-12-cloudflare),或者用 certbot 配置
|
|
||||||
|
|
||||||
最后 `sudo nginx -t` 以及 `sudo systemctl reload nginx` 一下就可以在相应域名看到初始界面啦。
|
|
||||||
|
|
||||||
### 媒体库路径
|
|
||||||
|
|
||||||
这个地方我摸了好一会才明白.
|
|
||||||
|
|
||||||
路径选择 media 或者 media2 下面的文件,然后后面的跟 cloudreve 里面的是一样的,比如在 cloudreve 中用户 1 创建的文件夹叫 jellyfin,则媒体库中路径为 `/media/1/jellyfin`
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
### 插件安装
|
|
||||||
|
|
||||||
Jellyfin 有很多实用的插件可以爬电影/音乐等元数据,可以在 `控制台-> 插件` 安装,需要注意的是,安装完插件需要重启一下才可以生效,也就是先`docker-compose down` 再 `docker-compose up -d`
|
|
||||||
|
|
||||||
目前感觉比较好用的两个插件:
|
|
||||||
|
|
||||||
- [Douban plugin for Jellyfin](https://github.com/Libitum/jellyfin-plugin-douban): 可以抓豆瓣的元数据,需要通过链接安装
|
|
||||||
- Open Subtitles:字幕资源,需要登录 [opensubtitles.com](https://www.opensubtitles.com/zh-CN),并获取 API
|
|
||||||
|
|
||||||
### 主题和语言
|
|
||||||
|
|
||||||
可以在`display` 里面更改界面语言和主题,我比较喜欢的主题是 Purple Haze, 感觉是有些克制的赛博朋克风格
|
|
|
@ -1,43 +0,0 @@
|
||||||
---
|
|
||||||
title: 一些设计作品
|
|
||||||
created: 2022-07-13
|
|
||||||
summary: logo / UI / 包装 / 儿童玩具 ……
|
|
||||||
---
|
|
||||||
|
|
||||||
## 二十四节气茶包
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
## UI 设计
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
## 饼干包装
|
|
||||||
|
|
||||||
升级前
|
|
||||||

|
|
||||||
升级后(面对年轻人重新设计
|
|
||||||

|
|
||||||
|
|
||||||
## Logo
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
## 排版装帧
|
|
||||||
|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||

|
|
||||||
|
|
||||||
## 儿童玩具
|
|
||||||
|
|
||||||

|
|
||||||
|
|
||||||
未完待续……(也不知道续不续)
|
|
|
@ -1,92 +0,0 @@
|
||||||
---
|
|
||||||
title: 我在看什么 · 6月
|
|
||||||
created: 2022-07-15
|
|
||||||
summary: Vue / 网页性能优化 / npm ……
|
|
||||||
tags:
|
|
||||||
- 我在看什么
|
|
||||||
image: /2022-07-15-reading-6/june.png
|
|
||||||
---
|
|
||||||
|
|
||||||
## 编程相关
|
|
||||||
|
|
||||||
### 前端
|
|
||||||
|
|
||||||
1. [Learn Debounce And Throttle In 16 Minutes](https://www.youtube.com/watch?v=cjIswDCKgu0)
|
|
||||||
|
|
||||||
讲得挺好的一个视频。
|
|
||||||
节流(debounce)和防抖(Throttle)是优化高频率执行代码的一种手段[^1] 如果把执行代码比喻成下楼拿快递的话:
|
|
||||||
|
|
||||||
- 不做任何处理时就是快递来了就下楼拿。
|
|
||||||
- 节流是不管快递来没来,每隔 10 分钟下一次楼。
|
|
||||||
- 防抖则是第一个快递来了,等上 10 分钟,要是在这个 10 分钟内第二个快递来了,就继续等 10 分钟看有没有第三个快递,如果 10 分钟内下一个快递没来就下楼拿前面的快递。
|
|
||||||
|
|
||||||
2. [基于 Vue 实现一个简易 MVVM](https://juejin.cn/post/6844904099704471559)
|
|
||||||
3. [Websocket 原理及具体使用(ws+socket.io)](https://juejin.cn/post/6857716625764777991)
|
|
||||||
4. [String.prototype.localeCompare()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)
|
|
||||||
|
|
||||||
- 一个用来比较字符串的方法,可以结合 sort 方法对字符串进行排序,因为 sort 方法是按 ASCII 值来排序的,很多时候使用表现并不好,结合`localeCompare`可以做到按大小写排序、对带有重音符号的字符排序……
|
|
||||||
- `localeCompare`接受三个参数:compareString、locales、options,其中 compareString(即用来比较的字符串)是必选的,其他为可选。
|
|
||||||
- `localeCompare`的返回值有三种,负数、正数、0,其中如果引用字符存在于比较字符之前则为负数; 如果引用字符存在于比较字符之后则为正数; 相等的时候返回 0 。
|
|
||||||
|
|
||||||
5. Pinia 和 Optional API 的结合使用
|
|
||||||
|
|
||||||
- [Access Pinia State in the Options API](https://vueschool.io/lessons/access-pinia-state-in-the-options-api)
|
|
||||||
- [Usage without setup()](https://pinia.vuejs.org/cookbook/options-api.html)
|
|
||||||
|
|
||||||
6. [How to Migrate from Vue CLI to Vite](https://vueschool.io/articles/vuejs-tutorials/how-to-migrate-from-vue-cli-to-vite/)
|
|
||||||
7. [使用 pnpm 替换 npm 优化项目开发](https://juejin.cn/post/7067801337076908068)
|
|
||||||
8. [剪贴板操作 Clipboard API 教程](https://www.ruanyifeng.com/blog/2021/01/clipboard-api.html)
|
|
||||||
9. [如何做前端单元测试](https://juejin.cn/post/7039108357554176037)
|
|
||||||
10. [Vue-测试](https://staging-cn.vuejs.org/guide/scaling-up/testing.html)
|
|
||||||
11. [前后端加密(一):前端请求加密封装](https://www.hsmus.top/202011210.html)
|
|
||||||
12. [深入浅出 npm & yarn & pnpm 包管理机制](https://mp.weixin.qq.com/s/ZTI-8RI0l314Ki9oBxqRWw)
|
|
||||||
> 很多人认为 npm 是 node package manager 的缩写,其实不是,而且 npm 根本也不是任何短语的缩写。
|
|
||||||
> 它的前身其实是名为 pm(pkgmakeinst) 的 bash 工具,它可以在各种平台上安装各种东西。
|
|
||||||
> 硬要说缩写的话,也应该是 node pm 或者 new pm。
|
|
||||||
13. [过度使用懒加载对 Web 性能的影响](https://juejin.cn/post/7074759905197948935)
|
|
||||||
14. [Vue 项目性能优化 — 实践指南(网上最全 / 详细)](https://juejin.cn/post/6844903913410314247)
|
|
||||||
15. [Vue 打包 chunk-vendors.js 文件过大解决方案(compression-webpack-plugin)](https://blog.csdn.net/zz00008888/article/details/119893222)
|
|
||||||
16. [解决 NPM 安装应用出现 ERESOLVE 错误](https://blog.alanwei.com/blog/2021/03/30/npm-install-eresulve-error/)
|
|
||||||
17. [Web 性能优化:FOUC](https://mp.weixin.qq.com/s/gCn_QwuhiT4aSKZB6bDs6g)
|
|
||||||
18. [傻傻分不清之 Cookie、Session、Token、JWT](https://juejin.cn/post/6844904034181070861)
|
|
||||||
19. [[译文]为什么 Angular 比 React 更适合企业级应用程序](https://juejin.cn/post/7060399592298250270)
|
|
||||||
|
|
||||||
### 后端
|
|
||||||
|
|
||||||
1. [Docker 从入门到实践](https://yeasy.gitbook.io/docker_practice/)
|
|
||||||
2. [Ubuntu 安装新版本 nodejs 的 5 种姿势](https://uzykj.com/_posts/javascript/nodejs/basic/2021-08-17-ubuntu-install-nodejs.html#%E5%A7%BF%E5%8A%BFa-%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91%E5%AE%89%E8%A3%85)
|
|
||||||
3. [npm does not support Node.js v10.19.0](https://askubuntu.com/questions/1382565/npm-does-not-support-node-js-v10-19-0)
|
|
||||||
|
|
||||||
## 其他
|
|
||||||
|
|
||||||
1. [详细的全自动追番教程:Sonarr+Jackett+qBittorrent+Jellyfin](https://www.dnlab.net/archives/65/)
|
|
||||||
2. [Open Source Alternative to](https://www.opensourcealternative.to/)
|
|
||||||
3. [在 GitHub 公开仓库中隐藏自己的私人邮箱地址](https://blog.walterlv.com/post/remove-personal-emails-from-public-repos.html)
|
|
||||||
4. [各种开发者文档的以往版本](https://devdocs.io/)
|
|
||||||
5. [Github 删除某个文件的所有提交记录](https://cloud.tencent.com/developer/article/1665810)
|
|
||||||
|
|
||||||
## 互联网哲学
|
|
||||||
|
|
||||||
1. [Who Actually Owns Your Device?](https://chuck.is/root/)
|
|
||||||
> What it means to truly own your device is having the power and ability to modify it at a system level should you choose to – even if you don’t know what you’re doing, you should have the right.
|
|
||||||
2. [Information forest](https://tyler.cafe/information_forest)
|
|
||||||
|
|
||||||
在产品沉思录周刊看到的推荐
|
|
||||||
|
|
||||||
> What should the browser of the 2020s be?
|
|
||||||
>
|
|
||||||
> What will a browser built for research, analysis, rabbit-hole exploration, messy thinking, and collaboration look like? These features are listed in the order I thought of them in, not necessarily by importance.
|
|
||||||
>
|
|
||||||
> 1. Graph visualization and mind mapping.
|
|
||||||
> 2. Interactive history and version control.
|
|
||||||
> 3. Predictive search paths.
|
|
||||||
> 4. Super Command-F (Superf).
|
|
||||||
> 5. Collaboration
|
|
||||||
> 6. Automatic scraping and clusterin
|
|
||||||
> 7. Built in word processing.
|
|
||||||
> 8. Backlinks.
|
|
||||||
> 9. An infinitely zoomable interface (ZUI)
|
|
||||||
|
|
||||||
相关阅读:[Next Browser](https://mp.weixin.qq.com/s/6vKJxVhXXqLvBqf_V1KCwQ)
|
|
||||||
|
|
||||||
[^1]: [什么是防抖和节流?有什么区别?如何实现?](https://vue3js.cn/interview/JavaScript/debounce_throttle.html#%E4%B8%80%E3%80%81%E6%98%AF%E4%BB%80%E4%B9%88)
|
|
|
@ -1,42 +0,0 @@
|
||||||
---
|
|
||||||
title: 我在看什么 · 5月
|
|
||||||
created: 2022-07-16
|
|
||||||
summary: Anki / JSDoc / 蘑菇 / Music-Map ……
|
|
||||||
tags:
|
|
||||||
- 我在看什么
|
|
||||||
image: /2022-07-16-reading-5/May1.jpg
|
|
||||||
---
|
|
||||||
|
|
||||||
## Productivity
|
|
||||||
|
|
||||||
- [How To Create ANKI Flashcards From Your Kindle Vocabulary Builder](https://learnoutlive.com/kindle-vocabulary-builder-anki-flashcards/)
|
|
||||||
- [SSH 使用入门](https://wiki.cheng-group.net/wiki/%E9%9B%86%E7%BE%A4%E4%BD%BF%E7%94%A8/ssh_note#ssh-%E4%BD%BF%E7%94%A8%E5%85%A5%E9%97%A8)
|
|
||||||
|
|
||||||
SCP 部分写得很清楚
|
|
||||||
|
|
||||||
- [如何使用 JSDoc 保证你的 Javascript 类型安全性](https://mp.weixin.qq.com/s/PcHu-DeZDQCdtWjzb-QkBA)
|
|
||||||
- [你不知道的 JSDoc](https://juejin.cn/post/7072685382323830821)
|
|
||||||
- [codecombat](https://codecombat.cn/)
|
|
||||||
|
|
||||||
哇哦,打游戏学编程
|
|
||||||
|
|
||||||
- [讓有效學習更簡單!Markdown 匯出到 Anki | 使用 Flashcards 外掛](http://jdev.tw/blog/6505)
|
|
||||||
- [建立一套完整的筆記複習流程,使用 Obsidian 插件 Spaced Repetition](https://ithelp.ithome.com.tw/articles/10280788?sc=iThomeR)
|
|
||||||
- [硬核必备:Web3 生存指南之防骗反诈安全手册(65 页)](https://web3caff.com/zh/archives/8304)
|
|
||||||
- [写作 12 年,我的经验和技巧](https://catcoding.me/p/writing-for-joy/)
|
|
||||||
|
|
||||||
## 有趣的
|
|
||||||
|
|
||||||
- [Maggie Appleton](https://maggieappleton.com/)
|
|
||||||
|
|
||||||
很喜欢的一个博客!设计很漂亮,博文图文结合读起来让人很愉悦,是我理想的博客样子
|
|
||||||
|
|
||||||
- [科普|“朝菌”毛头鬼伞的菇事](https://mp.weixin.qq.com/s/YeLuBH9VZ1l-bltKdEqxsw)
|
|
||||||
- ["I'm Not Like Other Girls"](https://www.youtube.com/watch?v=7nL-kgbbcBA)
|
|
||||||
> _not like other girls_ can also be used as an insult
|
|
||||||
- [Why Life Is So Boring (and why it's a good thing)](https://www.youtube.com/watch?v=Wuu-2CR8btw)
|
|
||||||
- [吃蘑菇前我都会跟它说会儿话,因为我知道它是活的](https://mp.weixin.qq.com/s/qrtfEJMRn3LH0W05nBIa5Q)
|
|
||||||
> 「在期刊的原文中,阿达玛斯基写道:“我们不应该期望快速地得到一个结果,尽管我们与猫和狗生活了几个世纪,但我们还没有破译它们的语言,而对真菌的电子通讯的研究还处于纯粹的婴儿阶段。”
|
|
||||||
>
|
|
||||||
> 这么一想也不无道理,你甚至连自己家的猫猫狗狗在说什么都没搞明白,为什么一定要期待先跟一颗蘑菇对话呢?」
|
|
||||||
- [Music-Map](https://www.music-map.com/)
|
|
|
@ -1,21 +0,0 @@
|
||||||
---
|
|
||||||
title: XSS 学习
|
|
||||||
created: 2022-07-26
|
|
||||||
tags:
|
|
||||||
- XSS
|
|
||||||
- Notes
|
|
||||||
---
|
|
||||||
|
|
||||||
介绍文章:
|
|
||||||
|
|
||||||
- [前端安全系列(一):如何防止 XSS 攻击? - 美团技术团队](https://tech.meituan.com/2018/09/27/fe-security.html)
|
|
||||||
- [Cross-site scripting(跨站脚本攻击) - 术语表 | MDN](https://developer.mozilla.org/zh-CN/docs/Glossary/Cross-site_scripting)
|
|
||||||
|
|
||||||
练习:
|
|
||||||
|
|
||||||
- [prompt(1) to win](https://prompt.ml/)
|
|
||||||
- 解答:[prompt.ml](https://github.com/cure53/XSSChallengeWiki/wiki/prompt.ml#level-1)
|
|
||||||
|
|
||||||
相关文章:
|
|
||||||
|
|
||||||
- [我自己博客的一个 XSS 的故事 | 离别歌](https://www.leavesongs.com/PENETRATION/xss-from-my-blog.html)
|
|
|
@ -1,161 +0,0 @@
|
||||||
---
|
|
||||||
title: 我在看什么 · 7 月
|
|
||||||
created: 2022-07-31
|
|
||||||
summary: eval / CSP&XSS / Commonplace Book ……
|
|
||||||
tags:
|
|
||||||
- 我在看什么
|
|
||||||
image: /2022-07-31-reading-7/july.webp
|
|
||||||
---
|
|
||||||
|
|
||||||
## 前端
|
|
||||||
|
|
||||||
- **关于类型数组 TypedArray**
|
|
||||||
|
|
||||||
- [TypedArray - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray)
|
|
||||||
- [Typed arrays - Binary data in the browser](https://www.html5rocks.com/en/tutorials/webgl/typed_arrays/)
|
|
||||||
|
|
||||||
- [Deep-copying in JavaScript using structuredClone](https://web.dev/structured-clone)
|
|
||||||
- [How not to learn TypeScript](https://fettblog.eu/how-not-to-learn-typescript/)
|
|
||||||
|
|
||||||
讲了 TypeScript 使用过程中经常犯的错误
|
|
||||||
|
|
||||||
- [25+ JavaScript Shorthand Coding Techniques](https://www.sitepoint.com/shorthand-javascript-techniques/)
|
|
||||||
|
|
||||||
`Math.floor` 的简写是`~~`
|
|
||||||
|
|
||||||
- **eval**
|
|
||||||
|
|
||||||
- [eval-MDN](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval#don.27t_use_eval.21)
|
|
||||||
|
|
||||||
- [Js 代替 eval 的方法](https://blog.csdn.net/yx_xuan/article/details/115342622)
|
|
||||||
```js
|
|
||||||
const evalAlter = fn => {
|
|
||||||
const Fn = Function
|
|
||||||
return new Fn('return' + fn)()
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- **Vue 函数式组件**
|
|
||||||
|
|
||||||
- [函数式组件](https://staging-cn.vuejs.org/guide/extras/render-function.html#functional-components)
|
|
||||||
- [Vue 函数式组件](https://juejin.cn/post/6867458052036624392)
|
|
||||||
|
|
||||||
- [Notion 编辑器是怎么实现的?](https://www.yuexun.me/blog/how-the-notion-editor-is-implemented/)
|
|
||||||
|
|
||||||
- [Content Security Policy 入门教程](https://www.ruanyifeng.com/blog/2016/09/csp.html)
|
|
||||||
- CSP 是什么:
|
|
||||||
> CSP 的实质就是白名单制度,开发者明确告诉客户端,哪些外部资源可以加载和执行,等同于提供白名单。它的实现和执行全部由浏览器完成,开发者只需提供配置
|
|
||||||
- 设置方法:
|
|
||||||
1. 在 http 头中声明
|
|
||||||
2. 在 meta 标签中声明
|
|
||||||
- 具体配置中:
|
|
||||||
1. 如果同一个限制选项使用多次,只有第一次会生效。
|
|
||||||
2. `script-src`和`object-src`是必设的,除非设置了`default-src`。
|
|
||||||
3. `script-src`不能使用`unsafe-inline`关键字(除非伴随一个`nonce`值),也不能允许设置`data:URL`。
|
|
||||||
- 补充阅读:
|
|
||||||
- [Web Security](https://infosec.mozilla.org/guidelines/web_security#content-security-policy)
|
|
||||||
- [Content security policy](https://web.dev/csp/)
|
|
||||||
- [前端安全系列(一):如何防止 XSS 攻击? - 美团技术团队](https://tech.meituan.com/2018/09/27/fe-security.html)
|
|
||||||
|
|
||||||
严格的 CSP 在 XSS 的防范中可以起到以下的作用:
|
|
||||||
|
|
||||||
- 禁止加载外域代码,防止复杂的攻击逻辑。
|
|
||||||
- 禁止外域提交,网站被攻击后,用户的数据不会泄露到外域。
|
|
||||||
- 禁止内联脚本执行(规则较严格,目前发现 GitHub 使用)。
|
|
||||||
- 禁止未授权的脚本执行(新特性,Google Map 移动版在使用)。
|
|
||||||
- 合理使用上报可以及时发现 XSS,利于尽快修复问题。
|
|
||||||
|
|
||||||
- [我自己博客的一个 XSS 的故事](https://www.leavesongs.com/PENETRATION/xss-from-my-blog.html)
|
|
||||||
|
|
||||||
> 浏览器在渲染 JavaScript 伪协议地址的时候,会先进行 URL 解码,再执行 JavaScript。
|
|
||||||
|
|
||||||
> 因为浏览器在解析 URL 的时候会进行 URL 解码,那么用户的输入理应进行 URL 编码后再放进 URL 中。这就是我修复这个漏洞的方法,让用户的输入按照浏览器解析的顺序进行编码:**先进行 unicode 编码再进行 url 编码。**
|
|
||||||
|
|
||||||
- [Ladle vs. Storybook: Measuring performance across project sizes](https://blog.logrocket.com/ladle-storybook-performance-project-sizes/)
|
|
||||||
|
|
||||||
这个博客的文章质量都很高
|
|
||||||
|
|
||||||
- [a fresh new web framework is out](https://www.youtube.com/watch?v=4boXExbbGCk)
|
|
||||||
|
|
||||||
## 后端
|
|
||||||
|
|
||||||
- [Linux 入侵检测](https://www.cnblogs.com/sanduo1314/p/7458415.html)
|
|
||||||
- [如何删除镜像、容器和数据卷?几个值得收藏的 docker 命令](https://juejin.cn/post/6914846299607171080)
|
|
||||||
- [HTTP 413 错误解决方法](https://www.cnblogs.com/jiahm/p/12357503.html)
|
|
||||||
|
|
||||||
总结一下:413 错误是因为上传文件的大小超过了限制,需要调整 Nginx 设置,比如在 server 里面加
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
client_max_body_size 8M; #配置请求体缓存区大小
|
|
||||||
|
|
||||||
client_body_buffer_size 128k; #设置客户端请求体最大值
|
|
||||||
|
|
||||||
fastcgi_intercept_errors on;
|
|
||||||
```
|
|
||||||
|
|
||||||
今天在安装 WordPress 主题时遇到了这个问题,上次遇到好像是在 Mastodon 上传表情包的时候(不确定)
|
|
||||||
|
|
||||||
- **关于 WordPress 上传限制这回事:**
|
|
||||||
- [【docker】wordpress 修改文件上传限制](https://blog.csdn.net/j84491135/article/details/105977073)
|
|
||||||
- [How to install & use nano in a running Docker container](https://techoverflow.net/2019/10/13/how-to-install-use-nano-in-a-running-docker-container/)
|
|
||||||
- 这样方便一点:[如何修改 wordpress docker 容器的文件上传尺寸限制?](https://blog.csdn.net/sitebus/article/details/97648177)
|
|
||||||
|
|
||||||
## 什锦
|
|
||||||
|
|
||||||
- [折腾火狐](https://mp.weixin.qq.com/s/HvDKWRPXZbFK4T8pXZTWNg)
|
|
||||||
- [中文博客榜](https://xyzrank.com/)
|
|
||||||
- [git add .,git add -A,git add -u,git add\* 的区别与联系](https://dingxuewen.com/article/about-git-add/)
|
|
||||||
- [Delightful lists](https://delightful.club/)
|
|
||||||
|
|
||||||
> Delightful lists are an effort to help bring change to this trend. To make freedom more discoverable again. This top-level project will allow navigation to all high-quality curated delightful lists created and maintained all over the web.
|
|
||||||
> Anyone that wishes to do so can create their own list, and thus create an entrypoint to freedom.
|
|
||||||
|
|
||||||
- [Computer Programming](https://homepage.cs.uri.edu/faculty/wolfe/book/Readings/Reading13.htm)
|
|
||||||
|
|
||||||
偶然进入的网站,没有入口也没有出口,比较有年代感了
|
|
||||||
|
|
||||||
> A set of rules that provides a way of telling a computer what operations to perform is called a programming language. There is not, however, just one programming language; there are many. In this chapter you will learn about controlling a computer through the process of programming. You may even discover that you might want to become a programmer.
|
|
||||||
|
|
||||||
- [Mentality](https://alearningaday.blog/2022/07/11/mentality/)
|
|
||||||
|
|
||||||
一点点鸡汤
|
|
||||||

|
|
||||||
|
|
||||||
- [白话开源和 Web3](https://mp.weixin.qq.com/s/6B8z5NJzsDNN54EIF9oRzQ)
|
|
||||||
|
|
||||||
原文:[Open source and web3, simplified](https://www.flyingpenguins.io/p/open-source-and-web3-simplified)
|
|
||||||
|
|
||||||
> “并非所有这些平台本身都开源,但重要的是,与服务模式绑定的收益会直接反馈在其原生代币的价值上。有了这样的设定,随着时间的推移将源代码开放出来的激励是巨大的,因为它让开发者更具活力,让基于服务的生态系统得以存续,并让人们相信,项目将会以最符合网络利益的方式持续运作(因为倘若不这样,它可以被"分叉",即容易被复制)”
|
|
||||||
|
|
||||||
> “它也不仅仅是代码。想想维基百科、Facebook、Uber、Linux —— 所有这些项目都是由少数人定义平台的规则,然后大量的人参与价值构建。在这些社区中进行价值捕获和分配面临各种困境 ──Facebook 或 Uber 模式让少数人暴富,维基百科或 Linux 模式则几乎无利可图。我上面描述的结构能够让用户参与价值的创造和捕获,既适用于 Facebook 也可用于 Linux。”
|
|
||||||
|
|
||||||
- [How to lazy load images in Hugo](https://flaviocopes.com/lazy-load-images-hugo/)
|
|
||||||
|
|
||||||
> Create the file `layouts/_default/_markup/render-image.html` in your theme with this content:
|
|
||||||
|
|
||||||
```html
|
|
||||||
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" loading="lazy" />
|
|
||||||
This makes the resulting HTML have the loading="lazy" attribute, which lazily loads images.
|
|
||||||
```
|
|
||||||
|
|
||||||
- [How Do Dolphins Choose Their Name?](https://www.discovermagazine.com/planet-earth/how-do-dolphins-choose-their-name)
|
|
||||||
> Dolphins identify themselves with a unique whistle that scientists have likened to a human name. Here's how they decide what to call themselves.
|
|
||||||
|
|
||||||
## Commonplace Book
|
|
||||||
|
|
||||||
- [Commonplace book-Method of knowledge compiling](https://en.wikipedia.org/wiki/Commonplace_book)
|
|
||||||
- [How To Keep A Commonplace Book - 2022 Edition](https://www.youtube.com/watch?v=NPqjgN-pNDw)
|
|
||||||
|
|
||||||
1. Intentionality
|
|
||||||
|
|
||||||
> every idea matters
|
|
||||||
|
|
||||||
> just collect very succinct quotes from biographies that i've read from books that i've read or from articles from of the internet that i've read and over time i ended up with this collection of very succinct sentences that but basically every one of these sentences they mean something every one of these words they mean something every expression that i put into this book they're all very deeply personal for me and also the act of writing for me is very personal because writing for me and journaling for me is a form of calming the brain because my brain does not shut up so point one keeping a commonplacebook on a physical notebook is a lot more deliberate
|
|
||||||
|
|
||||||
2. better editing
|
|
||||||
> writing on the paper at least
|
|
||||||
> for me liberates me from that uh illusion of
|
|
||||||
> perfection illusion of cleanliness that i get on a computer screen because i can
|
|
||||||
> cross everything out i can cross things out straight away and i can spot
|
|
||||||
> mistakes and you know weak sentences straight away
|
|
||||||
3. Crossing Disciplines
|
|
|
@ -1,21 +0,0 @@
|
||||||
---
|
|
||||||
title: Monkey Patch
|
|
||||||
created: 2022-08-06
|
|
||||||
summary: 猴子打补丁
|
|
||||||
toc: false
|
|
||||||
tag:
|
|
||||||
- Notes
|
|
||||||
---
|
|
||||||
|
|
||||||
[Monkey Patch - Wikipedia](https://en.wikipedia.org/wiki/Monkey%20patch)
|
|
||||||
|
|
||||||
> A **Monkey patch** is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program)."
|
|
||||||
|
|
||||||
也可以可以理解为基于原生功能(API)的一些自定义拓展?这个概念常在 Python 里面出现,也叫鸭子双关
|
|
||||||
|
|
||||||
[Checking if a JavaScript native function is monkey patched](https://mmazzarolo.com/blog/2022-07-30-checking-if-a-javascript-native-function-was-monkey-patched/)
|
|
||||||
|
|
||||||
> Monkey patching is a powerful but dangerous technique because the code you’re overriding is not in your control: future updates to the JavaScript engine may break some assumptions made in your patch and cause serious bugs.
|
|
||||||
> Additionally, by monkey patching code you don’t own, you might override some code that has already been monkey patched by another developer, introducing a potential conflict.
|
|
||||||
|
|
||||||
对于 JS 来说,Monkey patch 的问题在于:如果 JS 引擎更新了,可能会带来一些难以预计的 bug,这篇文章说了几种怎么检测是否存在 monkey patch 函数的方法,比如用 toString、iframe、proxy 等等,但都不是很完美,可以根据使用场景来决定用哪种方法
|
|
|
@ -1,183 +0,0 @@
|
||||||
---
|
|
||||||
title: 通用设计 VS. 包容性设计
|
|
||||||
created: 2022-08-14
|
|
||||||
summary: Universal Design VS. Inclusive Design
|
|
||||||
tag:
|
|
||||||
- Design
|
|
||||||
- Notes
|
|
||||||
image: /2022-08-14-design/photo.png
|
|
||||||
---
|
|
||||||
|
|
||||||
这篇博文为测试博文,是读论文[《通用设计与包容性设计原则的发展和挑战》](https://www.researchgate.net/publication/328981184_tongyongshejiyubaorongxingshejiyuanzedefazhanhetiaozhan)的学习笔记,内容可能有不对的地方,逻辑也可能不通顺,感兴趣的朋友可以再研究一下。
|
|
||||||
|
|
||||||
## 社会背景和起源
|
|
||||||
|
|
||||||
- **人口老龄化和失能者增加**
|
|
||||||
|
|
||||||
老人和失能者的社会境遇往往与普通人明显不同
|
|
||||||
|
|
||||||
- **设计师摩尔(Patricia Moore)的变装实验**
|
|
||||||
- **无障碍(Barrier-free)运动**
|
|
||||||
|
|
||||||
(20th50s)开启了公共政策和设计实践的变革
|
|
||||||
|
|
||||||
- 1963 年,英国建筑师戈登史密斯(Selwyn Goldsmith)出版了名为 **《为失能者设计》** 的综合建筑设计导则
|
|
||||||
- **失能人士权力运动**
|
|
||||||
- **全球层面存在的具有地缘特征的挑战**
|
|
||||||
|
|
||||||
诸如越来越多的移民和流动人口造成的族群和文化多样性 ;经济发展失衡和贫富分化 ;城市化进程对生活方式的影响等等
|
|
||||||
|
|
||||||
## 共同的理念
|
|
||||||
|
|
||||||
> 产品和环境应考虑全体公民的需求和权利
|
|
||||||
|
|
||||||
> 减少和消除失能者与普通人之间在生理和思想观念上的隔阂
|
|
||||||
|
|
||||||
> 努力帮助失能者融入主流群体
|
|
||||||
|
|
||||||
> 失能者提供的许多环境变化实际上能使每个人都从中受益,许多类似的功能可以普及推广,从而更便宜,更有吸引力,甚至更有市场,并且不会带有污名化和歧视性标签
|
|
||||||
|
|
||||||
## 相关概念
|
|
||||||
|
|
||||||
### 无障碍设计 Barrier-free Design
|
|
||||||
|
|
||||||
- 特点
|
|
||||||
|
|
||||||
针对<u>残疾人</u>考虑
|
|
||||||
|
|
||||||
- 障碍的尺度
|
|
||||||
- 永久性残疾 permanent disability
|
|
||||||
- 情境性残疾 situational disability
|
|
||||||
- 临时性残疾 temporary disability
|
|
||||||
- 设计的角度(障碍的具体原因)
|
|
||||||
- 视觉无障碍设计 visual
|
|
||||||
- 听觉无障碍设计 hearing
|
|
||||||
- 行动无障碍设计 mobility
|
|
||||||
- 认知无障碍设计 cognition
|
|
||||||
|
|
||||||
### 跨代设计 Transgenerational Design
|
|
||||||
|
|
||||||
- **起源**
|
|
||||||
|
|
||||||
美国雪城大学(Syracuse University)的**珀克尔**(James Pirkl)教授和他的同事们提出概念以及一系列适用于这一概念的指导方针和战略
|
|
||||||
|
|
||||||
- **定义**
|
|
||||||
|
|
||||||
主张产品、服务和环境同时满足**不同年龄**和能力人群的需求,尤其强调老年人应能与年轻人在同一环境中共事
|
|
||||||
|
|
||||||
### 全纳设计 Design for All
|
|
||||||
|
|
||||||
- **起源**
|
|
||||||
|
|
||||||
北欧斯堪的纳维亚地区
|
|
||||||
|
|
||||||
- **概念**
|
|
||||||
|
|
||||||
强调产品应被设计为可让最广泛的用户群使用,包容人类的多样性,尊重人的**平等**
|
|
||||||
|
|
||||||
### 通用设计 Universal Design
|
|
||||||
|
|
||||||
- **特点**
|
|
||||||
|
|
||||||
从商业利益角度
|
|
||||||
|
|
||||||
- **起源**
|
|
||||||
- **美国**建筑师、设计师和教育先驱梅斯(Ron Mace)
|
|
||||||
- 将概念从无障碍设计强调环境应**适合失能人士**的语境
|
|
||||||
- **概念**
|
|
||||||
|
|
||||||
强调产品和环境不需要作特别调整而尽最大可能为**所有人可用**的理念
|
|
||||||
|
|
||||||
- **NCSU 的通用设计原则**
|
|
||||||
|
|
||||||
- 具体原则
|
|
||||||
- 使用平等
|
|
||||||
- 使用灵活
|
|
||||||
- 使用简单直观
|
|
||||||
- 信息可觉察
|
|
||||||
- 容错
|
|
||||||
- 不费力
|
|
||||||
- 适于接近和使用的尺度与空间
|
|
||||||
- 三个层次
|
|
||||||
|
|
||||||
1. **价值**
|
|
||||||
|
|
||||||
- "平等观"
|
|
||||||
- 强调对所有的用户一视同仁。
|
|
||||||
需注意这种一视同仁并非出于漠视用户的差别,而是指产品、服务和环境对用户使用体验和价值的一致性,即用户所得结果的一致性,此一致性不应受用户能力差异的影响。
|
|
||||||
|
|
||||||
2. **需求**
|
|
||||||
- 强调尽可能降低对用户的能力要求,其所指的能力既包括了生理和感官能力,也涵盖了认知和表达。
|
|
||||||
- 一般选择以最低能力的用户为标准进行设计,从而使产品、服务和建成环境得以覆盖全体用户的使用能力范围。
|
|
||||||
3. **供给**
|
|
||||||
|
|
||||||
主张提供尽可能高的灵活性和容错能力
|
|
||||||
|
|
||||||
- **设计的目标**
|
|
||||||
1. 合身——适应各种体型和能力
|
|
||||||
2. 舒适——将需求保持在身体机能的理想限度内
|
|
||||||
3. 觉察——确保(产品)使用的关键信息易于获得
|
|
||||||
4. 理解——使操作和使用的方法直观、清晰、明确
|
|
||||||
5. 健康——有助于促进健康、避免疾病和预防伤害
|
|
||||||
6. 社会融合——以有尊严和尊重的方式对待所有群体
|
|
||||||
7. 个性化——包含选择机会和个人偏好的表达
|
|
||||||
8. 文化适宜性——尊重和加强设计项目的文化价值及社会和环境背景。
|
|
||||||
- **案例**
|
|
||||||
- 斜坡入口
|
|
||||||
- 自动门
|
|
||||||
- 杠杆门把手
|
|
||||||
- 平板灯开关
|
|
||||||
- 任务照明
|
|
||||||
|
|
||||||
### 包容性设计 Inclusive Design
|
|
||||||
|
|
||||||
- **起源**
|
|
||||||
|
|
||||||
英国
|
|
||||||
|
|
||||||
- **概念**
|
|
||||||
|
|
||||||
主旨是在认识到用户**群体多样性**的情况下,倡导主流的产品、服务和建成环境应尽可能满足更多人的需求 ,或者说,将设计可能产生的**排斥度降到最低**。
|
|
||||||
|
|
||||||
- **特点**
|
|
||||||
- 和通用设计与全纳设计强调在技术可能性允许的条件下将可及性最大化略有不同,包容性设计主张为产品、服务和建成环境选取**合适的市场区间**,通过降低对用户使用能力的要求,从而将产品的主要适用人群在合理的可能性下最大化,并提升用户体验和满意度
|
|
||||||
- 并不以失能者为中心,也避免采用“辅助技术”
|
|
||||||
- 注重每个个体的福祉,但不再刻意追求在一项设计中满足所有群体的需求。
|
|
||||||
- **意义**
|
|
||||||
|
|
||||||
包容性设计可以在有限的资源约束下,为创造尽可能多的普惠价值提供方法和途径,从而与辅助技术的发展相辅相成。
|
|
||||||
|
|
||||||
- **“群体金字塔”**
|
|
||||||

|
|
||||||
|
|
||||||
展现了群体中的个体能力多样性差异
|
|
||||||
|
|
||||||
- **方法论**
|
|
||||||
|
|
||||||
通过合理降低能力要求,提升在不同情境下广泛客户群的产品体验
|
|
||||||
|
|
||||||
- **案例**
|
|
||||||
- 微软推出的 Xbox Adaptive Controller
|
|
||||||
- Chrome 浏览器的无障碍字幕
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
- **通用设计**:
|
|
||||||
- 强调产品和环境无需做特别调整而尽最大可能为所有人而用。
|
|
||||||
- 例如:公共空间的斜坡入口设计,既可以满足使用轮椅的人的需求,同时又有利于骑自行车的孩子、使用步行者的老年人、推婴儿车的父母等其他所有人群的使用。
|
|
||||||
- **包容性设计**:
|
|
||||||
- 主张为产品、服务和建成环境选取合适的市场区间,通过降低对用户使用能力的要求,从而将产品的主要适用人群在合理的可能性下最大化。
|
|
||||||
- 例如:微软推出的 Xbox Adaptive Controller 是一款针对残疾玩家和运动技能较差的人的游戏机,它有更大的按键和更容易被打开的包装设计,残疾人可以不费力使用的同时,普通人也能轻松地使用。
|
|
||||||
|
|
||||||
总而言之,两者都有相同的出发点,即"帮助失能人群更好地融入主流群体",同时都务实地接受一种产品并不总是能够满足整个人群的需求。其中,通用性设计以全体大众为出发点,不特意针对某一类族群而设计,包容性则主张在满足特定困难人群需求的基础上辐射到最广泛人群上。
|
|
||||||
|
|
||||||
## Reference
|
|
||||||
|
|
||||||
- [Universal Design 101 | Rick Hansen Foundation](https://www.rickhansen.com/news-stories/blog/universal-design-101)
|
|
||||||
|
|
||||||
- [包容性设计(inclusive design)和通用设计(universal design)的区别是什么?](https://www.zhihu.com/question/26045305)
|
|
||||||
|
|
||||||
- [从无障碍设计中学习如何成为一个更好的设计师](https://zhuanlan.zhihu.com/p/119766231)
|
|
||||||
|
|
||||||
- [无障碍设计](https://zhuanlan.zhihu.com/p/31657525)
|
|
||||||
- [Microsoft-Inclusive Design](https://www.microsoft.com/design/inclusive/)
|
|
|
@ -1,114 +0,0 @@
|
||||||
---
|
|
||||||
title: VPS · 用 docker 安装语言学习工具 LWT
|
|
||||||
created: 2022-08-18
|
|
||||||
summary: Installing LWT with docker and docker composer
|
|
||||||
tag:
|
|
||||||
- VPS
|
|
||||||
- Self-host
|
|
||||||
- Docker
|
|
||||||
image: /2022-08-18-lwt/wizard.png
|
|
||||||
---
|
|
||||||
|
|
||||||
[LWT](https://learning-with-texts.sourceforge.io/) 是一个阅读分词软件,上传阅读材料后可以标记其中的生词并制卡复习,全称叫 Learning with Texts,不过我还没有怎么用过,详细的介绍可以看下面这几篇文章:
|
|
||||||
- [英语学习软件推荐——Learning with text (LWT) | 软通达](https://cyddgh.github.io/post/20220311154810/)
|
|
||||||
- [Learning With Text 使用全解(也许) - 知乎](https://zhuanlan.zhihu.com/p/463832139)
|
|
||||||
- [LWT(learning With Text) 本地化安装 - 知乎](https://zhuanlan.zhihu.com/p/473056398)
|
|
||||||
- Demo: [Learning With Texts (LWT)](https://learning-with-texts.sourceforge.io/testdb/index.php)
|
|
||||||
|
|
||||||
LWT 可以在本地安装也可以在 VPS 上安装,鉴于买了就要用的原则,我决定在VPS上安装看看。
|
|
||||||
|
|
||||||
我安装的 docker image 来源于:[GitHub - jsz4n/lwt-docker: Learning With Texts with Docker](https://github.com/jsz4n/lwt-docker),还有试过一些其他的 docker image ,都不太顺利,这安装介绍也写得不太清楚,几番周折之后,我修改了`docker-compose.yml` 中的部分内容后部署成功了,下面是我的搭建过程。
|
|
||||||
|
|
||||||
## 0. 准备
|
|
||||||
前提:安装好 docker 和 docker composer、nginx
|
|
||||||
|
|
||||||
如果还没安装的话,可以这样安装(Ubuntu):
|
|
||||||
```bash
|
|
||||||
sudo apt update
|
|
||||||
sudo apt install docker docker-compose
|
|
||||||
sudo apt install nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
准备一个解析好了的域名,如在 Cloudflare 里面配置域名`n.example.org` :添加一个A记录,名称为`n` ,内容为VPS的IP地址,如`123.123.123.14`
|
|
||||||
|
|
||||||
我之前安装了比较新的 docker composer版本(1.27.4),如果没有装新版的话,下面操作的`docker compose`请全部替换为`docker-compose`
|
|
||||||
|
|
||||||
## 1. 下载仓库源码
|
|
||||||
我决定在`/opt/`文件夹下面安装,首先进入opt文件夹
|
|
||||||
```bash
|
|
||||||
cd /opt
|
|
||||||
```
|
|
||||||
复制git仓库并进入文件夹
|
|
||||||
```bash
|
|
||||||
sudo git clone https://github.com/jsz4n/lwt-docker.git
|
|
||||||
cd lwt-docker
|
|
||||||
```
|
|
||||||
原README有讲需要本地 build 一下 image,但是感觉不是很必要?我直接用了 `suzanje/lwt:latest` 中的 image
|
|
||||||
## 2. 修改配置
|
|
||||||
|
|
||||||
打开`docker-compose.yml`文件:
|
|
||||||
```bash
|
|
||||||
sudo nano docker-compose.yml
|
|
||||||
```
|
|
||||||
修改密码:
|
|
||||||
```yaml title="docker-compose.yml" {7,15}
|
|
||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
|
||||||
mariadb:
|
|
||||||
image: mariadb:10.6
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- "MARIADB_ROOT_PASSWORD=密码" #改这里
|
|
||||||
volumes:
|
|
||||||
- ./media/:/var/lib/mysql
|
|
||||||
lwt:
|
|
||||||
image: suzanje/lwt:latest
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
- "MARIADB_SERVER=mariadb"
|
|
||||||
- "MARIADB_ROOT_PASSWORD=密码" #和上面的一样
|
|
||||||
ports:
|
|
||||||
- "8080:80" #如果需要改端口的话改8080的地方
|
|
||||||
depends_on:
|
|
||||||
- mariadb
|
|
||||||
```
|
|
||||||
|
|
||||||
## 3. 上线容器
|
|
||||||
```bash
|
|
||||||
sudo docker compose up -d
|
|
||||||
```
|
|
||||||
然后 `sudo docker compose ps` 一下看`lwt-docker-lwt-1` 和` lwt-docker-mariadb-1` 这两项的情况。
|
|
||||||
|
|
||||||
如果有错误的话,可以`sudo docker logs lwt-docker-lwt-1`看下日志
|
|
||||||
或者试着在`/opt/lwt-docker`文件夹下创建一个media文件夹:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo mkdir media
|
|
||||||
```
|
|
||||||
然后再重新上线容器
|
|
||||||
|
|
||||||
## 4. 配置反代和 SSL
|
|
||||||
我比较懒,设置还是跟之前的[配置 Cloudflare 的免费 SSL 证书](2022-06-12-cloudflare)里面一样配置,如果不想按照这个方法来配置反代的话可以参考:[利用 Nginx 进行反代](https://mantyke.icu/posts/2021/rsshub-miniflux/#%E5%88%A9%E7%94%A8nginx%E8%BF%9B%E8%A1%8C%E5%8F%8D%E4%BB%A3)中的配置
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo nano /etc/nginx/conf.d/lwt.conf
|
|
||||||
```
|
|
||||||
写入
|
|
||||||
```bash title="/etc/nginx/conf.d/lwt.conf" {2,4}
|
|
||||||
server {
|
|
||||||
listen 443 ssl;
|
|
||||||
server_name 域名;
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:8080;
|
|
||||||
proxy_set_header HOST $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
接着`sudo nginx -t` 之后 `sudo systemctl reload nginx` 重启nginx之后就可以在配置好的域名看到 LWT 啦
|
|
||||||
|
|
||||||
## 后续
|
|
||||||
如果我有继续使用的话后面可能会更新阅读配置和使用细节等内容(不确定)
|
|
BIN
urara/2022-09-02-reading-8/Augest.png
Normal file
BIN
urara/2022-09-02-reading-8/Augest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 MiB |
BIN
urara/2022-09-02-reading-8/augest.JPG
Normal file
BIN
urara/2022-09-02-reading-8/augest.JPG
Normal file
Binary file not shown.
After Width: | Height: | Size: 778 KiB |
|
@ -1,16 +1,16 @@
|
||||||
// vite define config
|
// vite define config
|
||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
// vite sveltekit
|
|
||||||
import { sveltekit } from '@sveltejs/kit/vite'
|
|
||||||
// vite plugin
|
// vite plugin
|
||||||
import UnoCSS from 'unocss/vite'
|
import UnoCSS from 'unocss/vite'
|
||||||
import { presetTagify, presetIcons, extractorSvelte } from 'unocss'
|
import { presetTagify, presetIcons, extractorSvelte } from 'unocss'
|
||||||
import { VitePWA } from 'vite-plugin-pwa'
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
|
import { sveltekit } from '@sveltejs/kit/vite'
|
||||||
// postcss & tailwindcss
|
// postcss & tailwindcss
|
||||||
import TailwindCSS from 'tailwindcss'
|
import TailwindCSS from 'tailwindcss'
|
||||||
import tailwindConfig from './tailwind.config'
|
import tailwindConfig from './tailwind.config'
|
||||||
import autoprefixer from 'autoprefixer'
|
import autoprefixer from 'autoprefixer'
|
||||||
import cssnano from 'cssnano'
|
import cssnano from 'cssnano'
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
envPrefix: 'URARA_',
|
envPrefix: 'URARA_',
|
||||||
css: {
|
css: {
|
||||||
|
|
Loading…
Reference in a new issue