Compare commits

...

4 commits

Author SHA1 Message Date
SevicheCC
3a101d930d
add whitespace 2023-05-09 02:06:17 +08:00
SevicheCC
d368b27ccb
update personal info 2023-05-09 01:58:33 +08:00
SevicheCC
b55b7e743e
merge with upstream 3f449443be 2023-05-09 01:43:16 +08:00
SevicheCC
f61de8a4ef
new posts and remark42 2023-05-09 00:55:32 +08:00
23 changed files with 4291 additions and 4534 deletions

View file

@ -1,7 +1,7 @@
{
"editor.formatOnSave": true,
"files.eol": "\n",
"typescript.tsdk": "node_modules\\typescript\\lib",
"typescript.tsdk": "node_modules/typescript/lib",
"css.lint.unknownAtRules": "ignore",
"svelte.plugin.css.diagnostics.enable": false,
"[html]": {

View file

@ -59,9 +59,7 @@ const remarkUraraSpoiler = () => (tree: Node<Data>) =>
return node
})
const defineConfig = (config: MdsvexOptions) => config
export default defineConfig({
export default {
extensions: ['.svelte.md', '.md'],
smartypants: {
dashes: 'oldschool'
@ -95,7 +93,7 @@ export default defineConfig({
[
remarkFFF as any,
{
presets: [],
presets: ['hugo'],
target: 'mdsvex',
autofill: {
provider: 'fs',
@ -118,4 +116,4 @@ export default defineConfig({
}
]
]
})
} as MdsvexOptions

View file

@ -1,8 +1,7 @@
[build]
command = "npx pnpm i --store=node_modules/.pnpm-store && npx pnpm build"
command = "corepack prepare pnpm@8.4.0 --activate && pnpm i && npx pnpm build"
publish = "build"
[build.environment]
NPM_FLAGS = "--version"
AWS_LAMBDA_JS_RUNTIME = "nodejs16.x"

View file

@ -25,73 +25,66 @@
"zhlint": "zhlint urara/*/*.md --fix && zhlint urara/*.md --fix"
},
"devDependencies": {
"@iconify-json/heroicons-outline": "^1.1.5",
"@iconify-json/heroicons-solid": "^1.1.6",
"@iconify-json/ic": "^1.1.12",
"@iconify-json/heroicons-outline": "^1.1.6",
"@iconify-json/heroicons-solid": "^1.1.7",
"@iconify-json/ic": "^1.1.13",
"@iconify-json/icon-park-twotone": "1.1.7",
"@iconify-json/material-symbols": "1.1.27",
"@iconify-json/mdi": "^1.1.45",
"@iconify-json/mdi": "^1.1.50",
"@iconify-json/simple-icons": "1.1.42",
"@iconify-json/uil": "^1.1.3",
"@sveltejs/adapter-auto": "^1.0.2",
"@iconify-json/uil": "^1.1.4",
"@sveltejs/adapter-netlify": "^1.0.5",
"@sveltejs/adapter-node": "^1.1.6",
"@sveltejs/adapter-static": "^1.0.6",
"@sveltejs/adapter-vercel": "1.0.6",
"@sveltejs/kit": "^1.3.10",
"@sveltejs/kit": "^1.16.2",
"@tailwindcss/typography": "^0.5.9",
"@types/node": "^18.11.18",
"@types/node": "^18.16.5",
"@types/unist": "^2.0.6",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vite-pwa/sveltekit": "^0.1.2",
"autoprefixer": "^10.4.13",
"@typescript-eslint/eslint-plugin": "^5.59.2",
"@typescript-eslint/parser": "^5.59.2",
"@unocss/extractor-svelte": "^0.51.12",
"@vite-pwa/sveltekit": "^0.1.3",
"chalk": "^5.2.0",
"chokidar": "^3.5.3",
"clsx": "^1.2.1",
"cross-env": "^7.0.3",
"cssnano": "^5.1.14",
"daisyui": "^2.50.0",
"eslint": "^8.33.0",
"eslint-config-prettier": "^8.6.0",
"daisyui": "^2.51.6",
"eslint": "^8.40.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-svelte3": "^4.0.0",
"fenceparser": "^2.2.0",
"fff-flavored-frontmatter": "~0.5.0",
"fff-flavored-frontmatter": "~0.5.3",
"github-slugger": "^2.0.0",
"mdast-util-to-string": "^3.1.1",
"mdast-util-to-string": "^3.2.0",
"mdsvex": "^0.10.6",
"netlify-cli": "^12.10.0",
"netlify-cli": "^15.0.2",
"npm-run-all": "^4.1.5",
"postcss": "^8.4.21",
"prettier": "^2.8.3",
"prettier-plugin-svelte": "^2.9.0",
"postcss": "^8.4.23",
"postcss-lightningcss": "^0.7.0",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.10.0",
"rehype-autolink-headings": "^6.1.1",
"rehype-external-links": "^2.0.1",
"rehype-external-links": "^2.1.0",
"rehype-slug": "^5.1.0",
"remark": "^14.0.2",
"remark-fff": "~0.5.0",
"remark-fff": "~0.5.3",
"remark-footnotes": "~2.0.0",
"rollup": "^3.13.0",
"shiki-twoslash": "^3.1.0",
"svelte": "^3.55.1",
"rollup": "^3.21.5",
"shiki-twoslash": "^3.1.2",
"svelte": "^3.59.1",
"svelte-bricks": "^0.1.7",
"svelte-check": "^3.0.3",
"svelte-preprocess": "^5.0.1",
"svelte-preprocess-import-assets": "^0.2.5",
"svelte-check": "^3.3.2",
"svelte-preprocess": "^5.0.3",
"svelte-typeahead": "^4.4.1",
"tailwindcss": "^3.2.4",
"sveltekit-embed": "^0.0.12",
"tailwindcss": "^3.3.2",
"tslib": "^2.5.0",
"typescript": "^4.9.5",
"unocss": "^0.49.4",
"vite": "^4.1.1",
"vite-imagetools": "^4.0.18",
"vite-plugin-pwa": "^0.14.1",
"typescript": "^5.0.4",
"unist-util-visit": "^4.1.2",
"unocss": "^0.51.12",
"vite": "^4.3.5",
"vite-imagetools": "^4.0.19",
"vite-plugin-pwa": "^0.14.7",
"workbox-build": "^6.5.4",
"workbox-window": "^6.5.4"
},
"pnpm": {
"overrides": {
"vite>rollup": "^3.13.0"
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,63 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte'
import type { Remark42Config } from '$lib/types/post'
export let post: Urara.Post
export let config: Remark42Config
let remark42Instance: any
onMount(() => {
const [c, s] = [document.createElement('script'), document.createElement('script')]
c.id = 'remark42_config'
c.type = 'application/javascript'
c.innerHTML = `
var remark_config = {
host: '${config.host}',
site_id: '${config.site_id || 'remark'}',
url: '${post.path}',
components: [${config.components || "'embed'"}],
max_shown_comments: ${config.max_shown_comments || 15},
max_last_comments: ${config.max_last_comments || 15},
theme: '${config.theme || 'light'}',
page_title: '${config.page_title || post.title}',
locale: '${config.locale || 'en'}',
show_email_subscription: ${config.show_email_subscription || true},
show_rss_subscription: ${config.show_rss_subscription || true},
simple_view: ${config.simple_view || false},
no_footer: ${config.no_footer || false},
}`
s.id = 'remark42_script'
s.type = 'application/javascript'
s.innerHTML = `!function(e,n){for(var o=0;o<e.length;o++){var r=n.createElement("script"),c=".js",d=n.head||n.body;"noModule"in r?(r.type="module",c=".mjs"):r.async=!0,r.defer=!0,r.src='${config.host}/web/'+e[o]+c,d.appendChild(r)}}(remark_config.components||["embed"],document);`
document.head.appendChild(c)
document.head.appendChild(s)
const opt = {
...config,
url: post.path
}
const checkRemark42 = () => {
if ((window as any).REMARK42) {
remark42Instance = (window as any).REMARK42.createInstance({
node: document.getElementById('remark42') as HTMLElement,
...opt
})
} else {
setTimeout(checkRemark42, 100)
}
}
checkRemark42()
})
onDestroy(() => {
if (remark42Instance && typeof remark42Instance.destroy === 'function') {
remark42Instance.destroy()
}
})
</script>
<div id="remark42" />

View file

@ -55,7 +55,7 @@
id="header"
class:-translate-y-32={!pin && scrollY > 0}
class="fixed z-50 w-screen transition-all duration-500 ease-in-out border-b-2 border-transparent max-h-[4.125rem] {scrollY >
32 && 'backdrop-blur border-base-content/10 bg-base-100/30 md:bg-base-200/30'}">
32 && 'backdrop-blur !border-base-content/10 bg-base-100/30 md:bg-base-200/30'}">
{#if !search}
<div in:fly={{ x: -50, duration: 300, delay: 300 }} out:fly={{ x: -50, duration: 300 }} class="navbar">
<div class="navbar-start">

View file

@ -22,7 +22,7 @@
<div
in:fly={{ x: 25, duration: 300, delay: 500 }}
out:fly={{ x: 25, duration: 300 }}
class="flex-1 w-full max-w-screen-md order-first ease-out transform mx-auto xl:mr-0">
class="flex-1 w-full order-first ease-out transform mx-auto xl:mr-0 xl:ml-0">
{#if browser}
<Action {post} />
{/if}
@ -30,7 +30,7 @@
<div
in:fly={{ x: -25, duration: 300, delay: 500 }}
out:fly={{ x: -25, duration: 300 }}
class="flex-1 w-full max-w-screen-md xl:order-last ease-out transform mx-auto xl:mr-0">
class="flex-1 w-full xl:order-last ease-out transform mx-auto xl:ml-0 xl:mr-0">
{#if browser && post.toc}
<div class="h-full hidden xl:block">
<Toc toc={post.toc} />

View file

@ -5,7 +5,7 @@ export const post: PostConfig = {
post: ['mastodon']
},
comment: {
use: ['Webmention', 'Giscus'],
use: ['Webmention', 'Giscus', 'Remark42'],
style: 'boxed',
webmention: {
username: 'seviche.cc',
@ -22,16 +22,10 @@ export const post: PostConfig = {
categoryID: 'DIC_kwDOHSra4c4CO9ua',
theme: 'light',
lang: 'en'
},
remark42: {
host: 'https://remark42.seviche.cc',
no_footer: true
}
// waline: {
// serverURL: 'https://waline-seviche.vercel.app/',
// lang: 'en',
// emoji: [
// 'https://cdn.jsdelivr.net/gh/norevi/waline-blobcatemojis@1.0/blobs',
// 'https://cdn.jsdelivr.net/gh/norevi/blob-emoji-for-waline@2.0/blobs-gif',
// 'ttps://cdn.jsdelivr.net/gh/norevi/blob-emoji-for-waline@2.0/blobs-png'
// ],
// requiredMeta: ['nick', 'mail']
// }
}
}

View file

@ -19,6 +19,24 @@ export const projects: Project[] = [
// img: 'https://usc1.contabostorage.com/cc0b816231a841b1b0232d5ef0c6deb1:image/2022/06/d4d2489936e4f647c25df6982c6ef924.png',
// link: 'https://haibian.seviche.cc'
// },
{
id: 'Raycast-miniflux',
name: 'Raycast - Miniflux',
tags: ['React', 'React Hooks', 'Miniflux', 'TypeScript'],
description: 'Search RSS entries from Raycast, and more features',
feature: 'React',
img: 'https://github.com/raycast/extensions/raw/3fdad375dd06b7f390b629235c6a10c37d05fc79/extensions/miniflux//media/commands.png',
link: 'https://www.raycast.com/SevicheCC/miniflux'
},
{
id: 'Raycast-Akkoma',
name: 'Raycast - Akkoma',
tags: ['React', 'React Hooks', 'Akkoma', 'TypeScript'],
description: 'Publish status from Raycast to Akkoma or Pleroma, and view your bookmarked status',
feature: 'React',
img: 'https://github.com/raycast/extensions/raw/42e765bc6bf970054fd69abfdc6ab3dd2ea4942d/extensions/akkoma//media/command.png',
link: 'https://www.raycast.com/SevicheCC/akkoma'
},
{
id: 'miniflux-injector',
name: 'Miniflux-injector',

View file

@ -4,14 +4,14 @@ export const site: SiteConfig = {
protocol: import.meta.env.URARA_SITE_PROTOCOL ?? import.meta.env.DEV ? 'http://' : 'https://',
domain: 'seviche.cc',
title: 'Seviche.cc',
subtitle: 'Tech / Code / Random Life',
subtitle: 'Random Frontend-Developer',
lang: 'zh',
description: 'Tech / Code / Random Life',
description: 'Random Frontend-Developer',
author: {
name: '酸橘汁腌鱼',
avatar: '/assets/avatar.jpg',
name: 'Seviche CC',
avatar: '/assets/avatar.png',
status: '🖤',
bio: ' Code / Tech <br> Living a Random Life ',
bio: 'Random Frontend-Developer',
metadata: [
{
icon: 'i-mdi-github',
@ -40,6 +40,6 @@ export const site: SiteConfig = {
// }
]
},
keywords: ['Tech', 'Code', 'Random Life'],
keywords: ['Tech', 'Code', 'Seviche CC', 'Frondend Developer', 'Programming'],
themeColor: '#3D4451'
}

View file

@ -1,10 +1,3 @@
import type { WalineEmojiInfo } from '@waline/client'
type WalineImageUploader = (image: File) => Promise<string>
type WalineHighlighter = (code: string, lang: string) => string
type WalineTexRenderer = (blockMode: boolean, tex: string) => string
export type PostConfig = {
bridgy?: {
[kind: string]: ('fed' | 'mastodon' | 'flickr' | 'github' | 'twitter')[]
@ -22,8 +15,7 @@ export type CommentConfig = {
giscus?: GiscusConfig
/** Utterances config, more at https://utteranc.es */
utterances?: UtterancesConfig
/** Waline config, more at https://waline.js.org/en/reference/component.html#texrenderer */
waline?: WalineConfig
remark42?: Remark42Config
}
export type WebmentionConfig = {
@ -81,7 +73,35 @@ export type UtterancesConfig = {
theme?: string
}
export type DisqusConfig = {
shortname: string
lang?: string
export type Remark42Config = {
/** hostname of Remark42 server, same as REMARK_URL in backend config, e.g. "https://demo.remark42.com" */
host: string
/** the SITE that you passed to Remark42 instance on start of backend. (default: remark) */
site_id?: string
/** url to the page with comments*/
url?: string
/** an array of widgets that should be rendered on a page (default: ['embed'] )*/
components?: ['embed' | 'last-comments' | 'counter']
/** maximum number of comments that is rendered on mobile version (default: 15 )*/
max_shown_comments?: number
/** maximum number of comments in the last comments widget (default: 15 )*/
max_last_comments?: number
/** changes UI theme, (default: light )*/
theme?: 'light' | 'dark'
/** title for current comments page (default: document.title)*/
page_title?: string
/**
* interface localization,
* English (en), Belarusian (be), Brazilian Portuguese (bp), Bulgarian (bg), Chinese (zh), Finnish (fi), French (fr), German (de), Japanese (ja), Korean (ko), Polish (pl), Russian (ru), Spanish (es), Turkish (tr), Ukrainian (ua), Italian (it) and Vietnamese (vi)
* default: en
*/
locale?: 'en' | 'be' | 'bp' | 'bg' | 'zh' | 'fi' | 'fr' | 'de' | 'ja' | 'ko' | 'pl' | 'ru' | 'es' | 'tr' | 'ua' | 'it' | 'vi'
/** enables email subscription (default: true) */
show_email_subscription?: boolean
/** enables RSS subscription, (default: true) */
show_rss_subscription?: boolean
/** minimized UI with basic info only, (default: false) */
simple_view?: boolean
/** hides footer with signature and links to Remark42,(default: false) */
no_footer?: boolean
}

View file

@ -1,30 +0,0 @@
<script lang="ts">
import { page } from '$app/stores'
import Head from '$lib/components/head.svelte'
import Footer from '$lib/components/footer.svelte'
</script>
<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-none w-full max-w-screen-md mx-auto xl:mx-0">
<article
itemscope
itemtype="https://schema.org/BlogPosting"
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">
<h1 class="opacity-20 text-6xl md:text-[12rem] -mt-2 mb-0">
{$page.status ?? '404'}
</h1>
<h2 class="-mt-12 md:-mt-24">{$page.error?.message ?? 'Not found'}</h2>
<div class="card-actions">
<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" />
Back to Home
</a>
</div>
</main>
</article>
<Footer sticky={true} class="flex-1 md:flex-initial" />
</div>
</div>

View file

@ -3,6 +3,7 @@
import { fly } from 'svelte/transition'
import { page } from '$app/stores'
import { browser } from '$app/environment'
import { goto } from '$app/navigation'
import { posts as storedPosts, tags as storedTags } from '$lib/stores/posts'
import { title as storedTitle } from '$lib/stores/title'
import Head from '$lib/components/head.svelte'
@ -26,7 +27,7 @@
$: if (tags) {
posts = !tags ? allPosts : allPosts.filter(post => tags.every(tag => post.tags?.includes(tag)))
if (browser && window.location.pathname === '/')
window.history.replaceState({}, '', tags.length > 0 ? `?tags=${tags.toString()}` : `/`)
goto(tags.length > 0 ? `?tags=${tags.toString()}` : `/`, { replaceState: true })
}
onMount(() => {

View file

@ -1,25 +1,22 @@
// sveltekit config type
import type { Config } from '@sveltejs/kit'
// svelte adapter
import adapterAuto from '@sveltejs/adapter-auto'
import adapterNode from '@sveltejs/adapter-node'
import adapterVercel from '@sveltejs/adapter-vercel'
import adapterNetlify from '@sveltejs/adapter-netlify'
import adapterStatic from '@sveltejs/adapter-static'
// svelte preprocessor
import { mdsvex } from 'mdsvex'
import mdsvexConfig from './mdsvex.config.js'
import importAssets from 'svelte-preprocess-import-assets'
import { vitePreprocess } from '@sveltejs/kit/vite'
const defineConfig = (config: Config) => config
export default defineConfig({
export default {
extensions: ['.svelte', ...(mdsvexConfig.extensions as string[])],
preprocess: [mdsvex(mdsvexConfig), importAssets(), vitePreprocess()],
preprocess: [mdsvex(mdsvexConfig), vitePreprocess()],
kit: {
adapter: Object.keys(process.env).some(key => ['VERCEL', 'NETLIFY'].includes(key))
? adapterAuto()
: process.env.ADAPTER === 'node'
? adapterNode({ out: 'build' })
adapter: Object.keys(process.env).some(key => key === 'VERCEL')
? adapterVercel()
: Object.keys(process.env).some(key => key === 'NETLIFY')
? adapterNetlify({ edge: true })
: adapterStatic({
pages: 'build',
assets: 'build',
@ -30,4 +27,4 @@ export default defineConfig({
},
csp: { mode: 'auto' }
}
})
} as Config

View file

@ -54,25 +54,25 @@ summary: 好像每个博客都有这么一篇博文呢
我不喜欢用手机,所以用得都不是很多,像支付宝、淘宝这些人均一个的就不说了
| 功能 | App |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 社交 | [Fedilab](https://fedilab.app/), [Tooot](https://tooot.app/), [Moshidon](https://github.com/LucasGGamerM/moshidon), [Megalodon](https://github.com/sk22/megalodon), [Kaiteki,](https://kaiteki.app/) |
| 密码 | bitwarden |
| 浏览器 | [Fennec](https://f-droid.org/packages/org.mozilla.fennec_fdroid/), [Kiwi Browser](https://kiwibrowser.com/) |
| 阅读 | Readwise Reader, 静读天下 Pro, 废文, 晋江, 长佩, |
| RSS | Miniflux 网页版, Readwise Reader |
| 效率 | Forest, [Yeolpumta](https://play.google.com/store/apps/details?id=com.pallo.passiontimerscoped), |
| 书签 | 浏览器自带,发给 Matrix 账号, Cubox |
| Git | [GitNex](https://gitnex.com/), Github |
| 搜索 | [Setter](https://github.com/scubajeff/Setter)(可以直接搜微博、公众号的内容) |
| 应用下载 | [Obtainium](https://github.com/ImranR98/Obtainium), [Driod-ify](https://github.com/Iamlooker/Droid-ify)( Goodbye [~~NeoStore~~](https://github.com/NeoApplications/Neo-Store)~~)~~ |
| 视频 | 其实很少看视频,但是这些挺好用的:[AnimePipe](https://codeberg.org/NullPointerException/AnimePipe), [Seal](https://github.com/JunkFood02/Seal), [LibreTube](https://libre-tube.github.io/) |
| 资讯 | 稀土掘金、[Hacki](https://github.com/Livinglist/Hacki) |
| 文件 | Syncthing |
| 图片 | [FIMO](https://fimo.app/), [Immich](https://immich.app/) |
| IM | ~~微信~~, Element, [FluttyChat](https://fluffychat.im/) |
| 系统工具 | [轻启动](https://wpengapp.com/lightstart)、[清浊](https://www.dircleaner.com/)、炼妖壶([Insular](https://secure-system.gitlab.io/Insular/))、[TrackerControl](https://trackercontrol.org/) |
| 输入法 | Gboard |
| 功能 | App |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 社交 | [Fedilab](https://fedilab.app/), [Tooot](https://tooot.app/), [Moshidon](https://github.com/LucasGGamerM/moshidon), [Megalodon](https://github.com/sk22/megalodon), [Kaiteki,](https://kaiteki.app/) |
| 密码 | bitwarden |
| 浏览器 | [Fennec](https://f-droid.org/packages/org.mozilla.fennec_fdroid/), [Kiwi Browser](https://kiwibrowser.com/) |
| 阅读 | Readwise Reader, 静读天下 Pro, 废文, 晋江, 长佩, |
| RSS | Miniflux 网页版, Readwise Reader |
| 效率 | Forest, [Yeolpumta](https://play.google.com/store/apps/details?id=com.pallo.passiontimerscoped), |
| 书签 | 浏览器自带,发给 Matrix 账号, Cubox |
| Git | [GitNex](https://gitnex.com/), Github |
| 搜索 | [Setter](https://github.com/scubajeff/Setter)(可以直接搜微博、公众号的内容) |
| 应用下载 | [Obtainium](https://github.com/ImranR98/Obtainium), [Driod-ify](https://github.com/Iamlooker/Droid-ify)( Goodbye [~~NeoStore~~](https://github.com/NeoApplications/Neo-Store)~~)~~ |
| 视频 | 其实很少看视频,但是这些挺好用的:[AnimePipe](https://codeberg.org/NullPointerException/AnimePipe), [Seal](https://github.com/JunkFood02/Seal), [LibreTube](https://libre-tube.github.io/) |
| 资讯 | 稀土掘金、[Hacki](https://github.com/Livinglist/Hacki) |
| 文件 | Syncthing |
| 图片 | [FIMO](https://fimo.app/), [Immich](https://immich.app/) |
| IM | ~~微信~~, Element, [FluttyChat](https://fluffychat.im/) |
| 系统工具 | [轻启动](https://wpengapp.com/lightstart)、[清浊](https://www.dircleaner.com/)、炼妖壶([Insular](https://secure-system.gitlab.io/Insular/))、[TrackerControl](https://trackercontrol.org/) [UrlChecker](https://github.com/TrianguloY/UrlChecker) |
| 输入法 | Gboard |
最近还发现几个蛮有意思的 App但是我用得不是很多

View file

@ -0,0 +1,91 @@
---
title: 我在看什么 · 2-4月
created: 2023-05-08
summary: 前端测试 / AI / 媒介
tags:
- 我在看什么
image: /2023-04-29-readings/cover.jpg
---
很久没更新这个系列了,因为博客构建时 Out of Memory 的问题,一直懒得去写什么,加上现在 AI 好像什么都会了,感觉写什么都没什么意义,「我想做的前人都做过了」,是这样的感觉。
这几个月没有看什么特别的东西,当然没有做什么特别的记录,之前每看一篇就要在 Fediverse 上记录,但是这样会打断思绪,也很容易沉浸到另一个语境中,感觉很低效,所以就没记录,然后下面的梳理来自 Readwise Reader 和 Cubox。
## 前端
- [Controlled and uncontrolled form inputs in React don't have to be complicated](https://goshacmd.com/controlled-vs-uncontrolled-inputs-react/)
- [Why It's So Hard to Check Object Equality in JavaScript](https://www.joshbritz.co/posts/why-its-so-hard-to-check-object-equality/)
> the main reason this happens is that (`===`) doesnt check that both objects have the same property keys and values. Instead, it checks that the two objects occupy the same place in memory.
- [What Is Serverless](https://www.youtube.com/watch?v=vxJobGtqKVM)
- [Serverless Functions Overview](https://vercel.com/docs/concepts/functions/serverless-functions)
- [前端测试体系和最佳实践](https://insights.thoughtworks.cn/frontend-testing/)
- [用GPT 从0搭建 Jest 到帮写测试用例](https://mp.weixin.qq.com/s/VjPb1bFy50njX_4QsfrREA)
- [End-to-End Testing With Playwright and Github Actions](https://www.builder.io/blog/end-to-end-testing-with-playwright-and-github-actions)
- [信息溯源:“前端已死”的论调是如何传播的?](https://mp.weixin.qq.com/s/yHIVEMPCc4YeQcM6WPtn8w)
- [The End of Front-End Development](https://www.joshwcomeau.com/blog/the-end-of-frontend-development/)
- [Let's Build a Chrome Extension That Steals Everything](https://mattfrisbie.substack.com/p/spy-chrome-extension)
- [纯函数和引用透明概念](https://caowenwei.github.io/%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B/pure-function-rt/)
> 简单的说,任意函数,或者任意代码段,如果它可以被它的计算结果直接替代,仍然不影响任何调用它的程序,那么这个函数或代码段就拥有引用透明的性质
- [Safari releases are development hell](https://www.construct.net/en/blogs/ashleys-blog-2/safari-releases-development-1616)
> Of course we had no idea that Safari wasn't due for release the next day. Some Apple employees tried to drop hints about a schedule they obviously weren't allowed to talk about, but couldn't manage anything much more specific than "soon". So we were forced to treat it as an emergency and act immediately.
- [JSONP demystified: What it is and why it exists - LogRocket Blog](https://blog.logrocket.com/jsonp-demystified-what-it-is-and-why-it-exists/)
- [Case Study - Analyzing Web Font Performance](https://www.keycdn.com/blog/web-font-performance)
- [Learn JavaScript Generators In 12 Minutes](https://www.youtube.com/watch?v=IJ6EgdiI_wU)
- [一行代码都不写用Cloudflare轻松做网站](https://orangeai.substack.com/p/cloudflare)
## AI
- [Sam Altman以及他的 AGI 烏托邦](https://shosho.tw/blog/sam-altman-agi-utopia/)
- [Moore's Law for Everything](https://moores.samaltman.com/)
> AI will lower the cost of goods and services, because labor is the driving cost at many levels of the supply chain.
- [GPT 4 and the Uncharted Territories of Language](https://www.fast.ai/posts/2023-03-20-wittgenstein.html)
> Perhaps it is only in grappling with the uncanny valley of language that we may find the strength to redefine our own linguistic boundaries and catch a fleeting glimpse of the world beyond the walls.
- [智能对话时代来临GUI正在向CUI演变](https://mp.weixin.qq.com/s/cLz6rcVlrwyys5yorItnTg)
- [一张估值20亿的“笑脸”正在拆掉OpenAI的围墙](https://mp.weixin.qq.com/s/uaIljNnF_TJjOnIzn6o5cw)
## 观点
- [以行动为中心的解释性媒介](https://mp.weixin.qq.com/s/z854s3E0tnVqVjTH9pKwpg)
> 解释性文字可能缺乏个性化和人际联系,但它可以更仔细地打磨;它不累,随时准备好;它可以嵌入图形和抽象符号;它可以被非线性地消耗;阅读它的速度比听言语要快;等等。也许最重要的是,它是一种大众媒介。
>视频游戏在这方面就很出色。有时教程会出现在非互动性过场动画中,与普通游戏截然不同,但更好的例子将指导和叙述呈现为互动环境中的无缝元素,而不会将镜头或控制权从玩家手中 “抢走”。其结果是在游戏环境中的丰富沉浸感 ——与棋盘游戏的指导手册形成鲜明的对比
> 在优秀的游戏中,叙事感觉像是对玩家行动的持续响应。这就打破了人们在阅读文本时与 “行动”分离的距离感。
> 复制/粘贴文档中的说明性文本没有行为和反应。对于使用者来说,这不是一个真正的动态媒介。
- 原文:[Doing-centric explanatory mediums: board game instruction manuals and an unusual Figma document](https://andymatuschak.org/doing-centric/)
- [How Developers Can Make money with Open Source Projects](https://rubygarage.org/blog/how-make-money-with-open-source-projects)
- [You have two jobs](https://jacobian.org/2017/nov/1/you-have-two-jobs/)
> You were hired to write code. Many developers make the mistake and think that their job stops there. Thats not true. In fact, you have two jobs:
> 1. Write good code.
> 2. Be easy to work with.
> “Easy to work with” means that you act professionally at all times. You disagree respectfully. You seek to understand before looking to be understood. You communicate clearly. You value your commitments
> Mostly, it means that you understand the value of relationships, and build them as carefully and intentionally as you build frameworks and libraries.
- [You Can Achieve Anything If You Focus On ONE Thing](https://dariusforoux.com/one-thing/)
- [Should we call them users? ](https://shapeofsoftware.com/should-we-call-them-users/?ref=shape-of-software-newsletter)
> Describing those people in a more nuanced and relatable way resulted in a positive shift in thinking across teams.
> So with all that in mind, the term "user" has feels even more odd to me now. I feel it strips the human from everybody. When seeing points on a graph and entries in a database it's easy to forget that these people are people at all.
> A company, team or designer should always push to be closer to the people powering their products and the language that is used sets a strong foundation for that. Every product is different, so ask yourself who you are building for.
- [你所嘗試的一切終究是徒勞 - Northern Wind](https://www.chunfuchao.com/posts/everything-you-do-is-ultimately-pointless/)
> 期待技術能解決人生問題就像期待考試考好能過上好人生一樣,最後只是緣木求魚。
## 设计
- [交互动效设计指南|深入浅出带你了解交互动效](https://mp.weixin.qq.com/s/G5XoQtzDcHF31TWuPgkjfA)
- [Can You Be a Designer if You Have No Training?](https://henry.codes/writing/can-you-be-a-designer-if-you-have-no-training/)
## 书籍
没一本看完的
> 那些以大写字母A开头的“艺术”Art似乎具有某种被称为“灵韵”aura的精神性被人们高高地供奉起来放进了博物馆。大写字母开头的“艺术”Art与小写字母开头的“艺术”art即一些大众艺术区分了开来。这种区分是现代社会发展的结果。高雅艺术与通俗艺术区分之后有教养者将自己的欣赏范围局限于前者而人民大众则既由于缺乏财力、时间和教育水平又由于觉得它苍白无力而去“寻找便宜而粗俗的物品”。 由此,造成了高雅艺术与通俗艺术的分野。这种分化对艺术的发展来说,是具有灾难性的,前者失去了大众,后者则失去了品味
>
> ——《艺术即经验》译者前言
> 当我们询问,绘画和音乐所表现的是什么意义时,我们是在要求一种从图像和声音的意义向语词意义的转换,而这本身就否定了图像和声音的意义的独特性。因此,艺术家是用形象来构思他们的作品的,这种形象同时也与艺术所使用的媒介,即实际的材料结合在一起。因此,这种思维,既是图像的思维,也是材料的思维。
>
> ——《艺术即经验》译者前言
> 批评可能很危险,主要是因为你批评的人常常觉得受到非难,无论你多么善解人意地发表评论,他都可能会以相同的方式反击。因为你伤害了他“宝贵的自尊”,他可能会觉得你是故意伤害他的,然后他也会试图伤害你。这种反击源于我称之为“错误的归因原则”的一种心理倾向——“我感到痛苦,因此我有这种感觉肯定是某个人的错”。
>
> ——《自恋也疯狂:面具下的极端自恋者》 约瑟夫·布尔戈(Joseph Burgo)
上个星期在看的:
- 《Javascript设计模式与开发实践》
- 《你不知道的Javascript

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

View file

@ -0,0 +1,95 @@
---
title: 最近在做的东西
created: 2023-04-29
summary: Raycast插件 / 鼠须管主题 / Akkoma 和 Forgejo备份脚本 / Shiraha
image: /2023-04-29-recent/certificate-fullstack.png
---
## Full Stack Open
为了学习 React我最近在学 [Full Stack Open](https://fullstackopen.com/),其实去年刚学完 JS 的时候有试着学但是当时觉得很吃力因为很多知识点教程里并不会深入去讲解只是提到了就给一个链接让人自己去看这样跳来跳去学的话感觉还蛮累的半天都还不能看完一Part看起来完全没进展所以我就没有学下去。
不过经过了一段时间的修炼,积累了一些各方面的知识之后,我又开始了,这次感觉轻松不少。
这个课一共有 14 个 Part0-7是 React 和一些 Node 相关的内容,后面还有 GraphQL、TypeScript、Docker 之类的主题,我目前是完成了前面部分的内容,后面的内容则想等需要的时候再去学。不过就算只完成了部分,也有相应的证书,好了,下面这是我的课程系列,证书以及摆在最前面了:
![](https://usc1.contabostorage.com/cc0b816231a841b1b0232d5ef0c6deb1:image/2023/05/f0be9416a34971fdaa943d32ff674400.png)
说一下感悟吧。
我觉得Full Stack Open 不太适合零基础入门如果之前没有学过框架或者类似的东西直接通过Full Stack Open 学习的话还是蛮难上手的教的内容都比较浅我之前Node、MongoDB、Vue之类的都有学过所以这次感觉还算轻松。
其次Full Stack Open 教的内容有些过时了,就像 Kwaa 说的,或许应该一开始就上 TypeScript。以及比起英文版中文翻译是更为过时的版本建议不要看中文版可以浏览器开翻译插件看英文版前面两Part中文版翻译还可以但是后面不仅内容过时排版也很错乱Promise 翻译成「承诺」也让人很难理解。
不过,我很喜欢 Full Stack Open 的教学方式,文章+练习,文章里面用例子 A 来讲述原理和操作而练习里面则用和A非常相似的项目来做练习这样能避免直接抄代码练习也是循序渐进的一步一步完成让人压力没这么大。
## Raycast插件开发
![](https://usc1.contabostorage.com/cc0b816231a841b1b0232d5ef0c6deb1:image/2023/05/84e1561d2438833ca85121ddd17efcf1.png)
**事情的发展**
为了练习 React 我开始写 Raycast 的 Miniflux 插件:[Miniflux](https://www.raycast.com/SevicheCC/miniflux) ,后面写着写着发现不太会处理缓存,于是又跑去写 [Akkoma插件](https://www.raycast.com/SevicheCC/akkoma) 想着这是个只能发帖文的插件功能简单实现起来应该也很简单吧乱七八糟地写了一通终于懂Raycast是怎么缓存的了在这两个插件上架后又开始在 Akkoma 的基础上做 Mastodon 的插件,但是改之前忘记搜下看有没有人在做了,于是现在暂时搁置了:[Add Mastodon extension](https://github.com/raycast/extensions/pull/6156) , 可能过几天会开始合之前别人的代码、加功能。
以及最近发现在 Miniflux 前端搜索内容的时候,条目内容总比通过调用 API 搜出来的结果少,不知道为什么。
**难点和不解**
写 Raycast 插件,一开始最让我不解的是:什么 Command 和什么组件对应?后面发现 Command 名是和组件名绑定的,需要在 `package.json` 里面指定,如图所示:
![](https://usc1.contabostorage.com/cc0b816231a841b1b0232d5ef0c6deb1:image/2023/05/cb3019fbd705039e35845f4af221c5ef.png)
- 某次 Publish 的时候,把我的本地代码全删了,详见:[Local codebase deleted after running npm run publish](https://github.com/raycast/extensions/issues/6086)
- 不用 masto.js 也可以实现授权和认证(这玩意对 Mastodon 以外的系列不太友好,试了几次都没成功),我最后是参考官方给的例子实现的
- 开发的时候可以用 pnpm ,但是 Publish 的时候要用 npm会检查里面有没有 package-lock.json)
**所以到底写了什么插件**
- Akkoma发送定时帖文、用 Markdown 写帖文、查看书签和自己的最近20条贴文、草稿功能……
- Miniflux搜索内容、增加订阅源、收藏内容到 Readwise Reader……
- Mastodon功能和 Akkoma 的一样,之后还会加功能
看起来非常实用,但写完之后我基本没怎么用过(笑)
**推荐的参考**
- [Create Your First Extension - Raycast API](https://developers.raycast.com/basics/create-your-first-extension)
- [Raycast 插件简明体验](https://zsakvo.notion.site/Raycast-b4998b2deca348f5b9192af2838e074f)
如果你也想写 Raycast 插件但是不知道写什么的话,我有一个想法,或许可以用这个 API 写写看:[Geniu](https://docs.genius.com) ,这是一个歌词信息的平台,我想这有很多可以实现的。
## 乱七八糟的东西
### 鼠须管主题
![](https://usc1.contabostorage.com/cc0b816231a841b1b0232d5ef0c6deb1:image/2023/05/2c1c5920ed276ed0c2de535924edfcb4.png)
一个Nord配色的鼠须管主题[nord-light](https://gist.github.com/Sevichecc/ae49279fbc12b633697e05fd832559e9)
作为一个血管里都流着Nord色血液的人我时间还想写个 [NetNewsWire](https://netnewswire.com/) 的Nord主题但前几天发现这玩意竟然有一个多 G想着「好嘛这不就省事了」就把它卸载了故事就暂时到这里了。
参考:[微信键盘配色鼠须管皮肤](https://gist.github.com/zsakvo/fff6e4859265d5d629439d5ccb553f8a)
### Forgejo和Pleroma备份脚本
前段时间从 Pleroma 搬到 Akkoma 了,感想:好 卡 啊!然后把 Pleroma 备份脚本修理了一下:
- [pleroma-backup-script](https://github.com/Sevichecc/pleroma-backup-script)
- [forgejo-backup-script](https://codeberg.org/Sevichecc/forgejo-backup-script)
本来是写了一个 service 定时备份这两个的,不知怎的,使徒袭来,没有工作起来,于是现在在手动 bash 了,或许过段时间修理一下。以及我觉得是 crontab 的权限我没设置好,所以 Music Bot 和定时备份都没生效。
## PR和Commit
- 修了 [Mangane](https://github.com/BDX-town/Mangane)的几个 Bug
- 为 [shiraha](https://shiraha.js.org/)写了几个样式 Material Design 3的样式
- 为博客加了 Remark42 评论插件
## 后续开源相关计划
- 完成 Airbnb Clone 项目
- shiraha 继续补充样式
- 修 Mangane 的 bug

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 KiB

View file

@ -9,7 +9,7 @@ flags:
import Profile from '$lib/components/extra/profile.svelte'
</script>
<Profile subname="sevichecc" bio={`普通的写码人最近在学Vue3和TypeScript`} >
<Profile subname="sevichecc" bio={`An ordinary front-end engineer who spends her days wrestling with CSS and JavaScript at work, but dreams about the exciting world of backend development at night.`} >
<div class="flex flex-col md:flex-row gap-4 mt-4">
<a href="https://matrix.to/#/@seviche:kongwoo.icu" rel="noopener external" target="_blank" class="group flex-1 relative overflow-hidden btn btn-block normal-case border-none no-underline bg-[#110019] hover:bg-[#0077B3]">
@ -26,23 +26,49 @@ flags:
我是 Seviche意为「酸橘汁腌鱼」这是朋友给我起的名字你也可以叫我「鱼」。大学的时候在学工业设计然后现在在学前端对 UX/交互设计也有一些了解。
这里是我的部落格,随便看看喔。
## 接触过的技术
### 姑且熟悉
`JavaScript` | `TypeScript` | `React`| `Redux` | `Vue.js` | `Nuxt.js`| `TailwindCSS` | `SASS`
### 简单用过
`Shell Script` |`Svelte` | `Deno JS` | `NodeJS` | `Express.js` | `Mongoose` `MongoDB` | `Prisma`
### 了解
`MySQL` | `Styled Components`
## 最近
### 在做
[ ] 找工作 (广州的前端岗位求推荐 😭)
[ ] [Airbnb clone](https://github.com/Sevichecc/Airbnb-Clone)
[ ] [Seigwai](https://codeberg.org/Sevichecc/Seigwai)
### 完成
[x] [Full Stack Open](https://fullstackopen.com/) (Part 1 Part7) (2023.1-2023.4)
[X] [Raycast Extension for Miniflux](https://www.raycast.com/SevicheCC/miniflux) (2023.4)
[X] [Raycast Extension for Akkoma](https://www.raycast.com/SevicheCC/akkoma) (2023.4)
[X] Pleroma 和 Forgejo 的备份脚本
- Pleroma [pleroma-backup-script](https://github.com/Sevichecc/pleroma-backup-script)
- Forgejo: [forgejo-backup-script](https://codeberg.org/Sevichecc/forgejo-backup-script)
### 联系我
可以通过[Matrix](https://matrix.to/#/@seviche:kongwoo.icu)或者通过邮箱联系我,如果需要发加密邮件的话,我的 GPG 公钥是: [`CFD2 D8F4 88C6 E58C 1735 FD88 CCE2 DDDD DDDD DDDD`](/assets/DDDDDDDD.asc) (`ed25519/CCE2DDDDDDDDDDDD`),邮箱:
可以通过 [Matrix](https://matrix.to/#/@seviche:kongwoo.icu) 或者通过邮箱联系我,如果需要发加密邮件的话,我的 GPG 公钥是: [`CFD2 D8F4 88C6 E58C 1735 FD88 CCE2 DDDD DDDD DDDD`](/assets/DDDDDDDD.asc) (`ed25519/CCE2DDDDDDDDDDDD`),邮箱:
```
window.atob("aGlAc2V2aWNoZS5jYw==")
hi[[@]]seviche.cc
```
### 写码进度
<a href='https://www.codewars.com/users/sevichecc'><img src='https://www.codewars.com/users/sevichecc/badges/micro?theme=light' alt='codewar badge'/></a>
<a href="https://wakatime.com/@75cfdcbc-7bca-41ef-90d1-b47d27818b7d"><img src="https://wakatime.com/badge/user/75cfdcbc-7bca-41ef-90d1-b47d27818b7d.svg?style=social" alt="Total time coded since Apr 12 2022" /></a>
### 博客日志
<a href='https://www.codewars.com/users/sevichecc'><img src='https://www.codewars.com/users/sevichecc/badges/micro?theme=light' alt='codewar badge'/></a>
### 博客日志
- 2023-04-29 Out of Memory
- 2022-05-06 从 Zola 搬到 Urara
- 之前:静态博客尝试过 Hugo / Zola / Hexo / Nextra ,动态博客尝试过 Ghost / WordPress / QQ 空间(?,部署平台 Vercel 和 Netlify 都试过,目前还没有试过的是 CloudFare Page。

BIN
urara/assets/avatar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 MiB

View file

@ -2,37 +2,27 @@
import { defineConfig } from 'vite'
// vite plugin
import UnoCSS from 'unocss/vite'
import { presetTagify, presetIcons, extractorSvelte } from 'unocss'
import { presetTagify, presetIcons } from 'unocss'
import extractorSvelte from '@unocss/extractor-svelte'
import { imagetools } from 'vite-imagetools'
import { SvelteKitPWA } from '@vite-pwa/sveltekit'
import { sveltekit as SvelteKit } from '@sveltejs/kit/vite'
import { SvelteKitPWA } from '@vite-pwa/sveltekit'
// postcss & tailwindcss
import TailwindCSS from 'tailwindcss'
import tailwindConfig from './tailwind.config'
import autoprefixer from 'autoprefixer'
import cssnano from 'cssnano'
import LightningCSS from 'postcss-lightningcss'
export default defineConfig({
envPrefix: 'URARA_',
build: {
sourcemap: false,
rollupOptions: {
cache: false
}
},
envPrefix: 'URARA_',
css: {
postcss: {
plugins: [
TailwindCSS(tailwindConfig),
autoprefixer(),
...(process.env.NODE_ENV === 'production'
? [
cssnano({
preset: ['default', { discardComments: { removeAll: true } }]
})
]
: [])
]
plugins: [TailwindCSS(tailwindConfig), LightningCSS()]
}
},
plugins: [