diff --git a/articles b/articles index 3744bd7..d1d724d 160000 --- a/articles +++ b/articles @@ -1 +1 @@ -Subproject commit 3744bd78995594e5fdfcaeff32f426f1d41daffa +Subproject commit d1d724d1170e8cd2460cf1beb5098161ac33ef9a diff --git a/src/lib/app.scss b/src/lib/app.scss index 37f2f17..a6480d9 100644 --- a/src/lib/app.scss +++ b/src/lib/app.scss @@ -6,7 +6,7 @@ } :root { - font-size: 16px; + font-size: 18px; } body { @@ -15,5 +15,5 @@ body { color: #ffffff; font-family: 'ZenKakuGothicNew-Regular', '游ゴシック体', 'Yu Gothic', YuGothic, 'ヒラギノ角ゴシック Pro', 'Hiragino Kaku Gothic Pro', 'メイリオ', Meiryo, Osaka, 'MS PGothic', sans-serif; - font-size: 16px; + font-size: 1rem; } \ No newline at end of file diff --git a/src/lib/article.ts b/src/lib/article.ts index 352397d..bcb748f 100644 --- a/src/lib/article.ts +++ b/src/lib/article.ts @@ -7,6 +7,8 @@ export type Article = { category: string; released_at: Date; updated_at: Date; + author: string; + email: string; tags: string[]; image: string; publish: Publish; diff --git a/src/lib/blog.scss b/src/lib/blog.scss index 95a98c9..ea34c95 100644 --- a/src/lib/blog.scss +++ b/src/lib/blog.scss @@ -1,231 +1,243 @@ .document { - --color-text: #ffffff; - --color-concept: hsla(40, 100%, 90%, 0.5); - --color-concept-hsl: 39, 100%, 25%; - --color-outline: #ffffff40; - width: 100%; + --color-text: #ffffff; + --color-concept: hsla(40, 100%, 90%, 0.5); + --color-concept-hsl: 39, 100%, 25%; + --color-outline: #ffffff40; + width: 100%; - color: var(--color-text); + color: var(--color-text); - h1 { - position: relative; - width: auto; - font-size: 2rem; - margin-bottom: 0.5rem; - } + padding-left: 2rem; + box-sizing: border-box; - hr { - padding: 0; - margin: 0; - border: none; - border-top: 1px solid var(--color-outline); - } + h1 { + position: relative; + width: auto; + font-size: 1.8rem; + margin-bottom: 0.5rem; + margin-left: -1rem; + } - >*:not(h1, hr) { - margin-left: 2rem; - } + hr { + padding: 0; + margin: 0; + border: none; + border-top: 1px solid var(--color-outline); + margin-left: -1rem; + } - h2 { - font-size: 1.5rem; - position: relative; + h2 { + font-size: 1.5rem; + position: relative; - &::before { - content: '#'; - position: absolute; - top: 0; - left: -1.5rem; - font-size: 1.75rem; - color: rgb(131, 131, 131); - } - } + // &::before { + // content: '#'; + // position: absolute; + // top: 0; + // left: -1.5rem; + // font-size: 1.75rem; + // color: rgb(131, 131, 131); + // } + } - h3 { - font-size: 1.25rem; - } + h3 { + font-size: 1.25rem; + } - h4 { - font-size: 1.05rem; - } + h4 { + font-size: 1.05rem; + } - hr { - border: none; - border-top: 1px solid var(--color-outline); - } + hr { + border: none; + border-top: 1px solid var(--color-outline); + } - img { - max-height: 300px; - } + img { + max-height: 300px; + } - a { - color: var(--color-text); - position: relative; - display: inline-block; - transform: translate(0, 0); - text-shadow: 0 0 1rem hsl(var(--color-concept-hsl)); - transition: 0.2s ease-out; - font-weight: normal; + a { + color: var(--color-text); + position: relative; + display: inline-block; + transform: translate(0, 0); + text-shadow: 0 0 1rem hsl(var(--color-concept-hsl)); + transition: 0.2s ease-out; + font-weight: normal; - &:hover { - transform: translate(0, -0.1rem); - } - } + &:hover { + transform: translate(0, -0.1rem); + } + } - blockquote { - position: relative; - font-size: 1.1rem; - font-weight: bold; - padding: 0; - padding-left: 1rem; - color: rgb(162, 162, 162); + blockquote { + position: relative; + font-size: 1.1rem; + font-weight: bold; + padding: 0; + padding-left: 1rem; + color: rgb(162, 162, 162); - &::before { - content: '“'; - position: absolute; - top: 0; - left: -0.5rem; - font-size: 2rem; - color: rgb(131, 131, 131); - } - } + &::before { + content: '“'; + position: absolute; + top: 0; + left: -0.5rem; + font-size: 2rem; + color: rgb(131, 131, 131); + } + } - warn { - position: relative; - display: block; - padding: 1rem 0.7rem 0.7rem; - background-image: linear-gradient(to right, var(--color-outline), transparent 75%); - background-origin: border-box; - box-shadow: inset 0 0 0 100vh var(--background-color); - text-shadow: 0 0 1rem hsl(var(--color-concept-hsl), 1); - border: 1px solid transparent; + warn { + position: relative; + display: block; + padding: 1rem 0.7rem 0.7rem; + background-image: linear-gradient(to right, var(--color-outline), transparent 75%); + background-origin: border-box; + box-shadow: inset 0 0 0 100vh var(--background-color); + text-shadow: 0 0 1rem hsl(var(--color-concept-hsl), 1); + border: 1px solid transparent; + border-radius: 0.5rem; + + &::before { + content: 'note:warn'; + position: relative; + display: block; + top: 0; + font-size: 0.8rem; + margin-bottom: -0.3rem; + transform: translate(0, -0.5rem); + text-shadow: 0 0 1rem red; + } + } + + code:not(pre>code) { + display: inline-block; + font-family: monospace; + font-size: 0.9rem; + background: #66666666; + padding: 0 0.3rem; border-radius: 0.5rem; + } - &::before { - content: 'note:warn'; - position: relative; - display: block; - top: 0; - font-size: 0.8rem; - margin-bottom: -0.3rem; - transform: translate(0, -0.5rem); - text-shadow: 0 0 1rem red; - } - } + pre { + font-family: monospace; + position: relative; + display: block; + margin-top: 0.75rem; + margin-bottom: 0.75rem; + // border: 2px solid #ffffff40; + border-radius: 0.5rem; + overflow-x: auto; + font-size: 0.9rem; - pre { - font-family: monospace; - position: relative; - display: block; - margin-top: 0.75rem; - margin-bottom: 0.75rem; - border: 2px solid #ffffff40; - border-radius: 0.5rem; - overflow-x: scroll; + &::-webkit-scrollbar { + border-radius: 10px; + height: 10px; + width: 8px; + background: #3d3d3d; + } - &::-webkit-scrollbar { - border-radius: 10px; - height: 10px; - width: 8px; - } + &::-webkit-scrollbar-thumb { + background: #6f6f6f; + border-radius: 10px; + } - &::-webkit-scrollbar-thumb { - background: #999; - border-radius: 10px; - } + &::-webkit-scrollbar-track { + border-radius: 10px; + } - &::-webkit-scrollbar-track { - border-radius: 10px; - } + > code { + display: inline-block; + padding: 0.5rem; + border-radius: 0.6rem; + font-family: monospace; + box-sizing: border-box; + min-width: 100%; + } + } - >code { - display: inline-block; - padding: 0.5rem; - border-radius: 0.6rem; - font-family: monospace; - box-sizing: border-box; - min-width: 100%; - } - } + details { + position: relative; + display: block; + border-radius: 0.5rem; + transition: 0.2s ease-out; + transition-property: height; + padding-inline-start: 0.1rem; - details { - position: relative; - display: block; - border-radius: 0.5rem; - transition: 0.2s ease-out; - transition-property: height; - padding-inline-start: 0.1rem; + > summary { + position: relative; + border-radius: 0.5rem; + list-style: '+ ' outside; + margin-left: 1rem; + padding: 0.2rem; + background: linear-gradient(to right, rgba(255, 255, 255, 0.25), transparent 200px); + cursor: pointer; - >summary { - position: relative; - border-radius: 0.5rem; - list-style: '+ ' outside; - margin-left: 1rem; - padding: 0.2rem; - background: linear-gradient(to right, rgba(255, 255, 255, 0.25), transparent 200px); - cursor: pointer; + &:hover { + text-shadow: 0 0 0.25rem rgb(255, 255, 255); + } + } - &:hover { - text-shadow: 0 0 0.25rem rgb(255, 255, 255); - } - } + > p { + margin-block-start: 0.5rem; + margin-block-end: 0.5rem; + margin-left: 1rem; + display: none; + } - >p { - margin-block-start: 0.5rem; - margin-block-end: 0.5rem; - margin-left: 1rem; - display: none; - } + &[open] { + > summary { + list-style: '- ' outside; + } - &[open] { - >summary { - list-style: '- ' outside; - } + > p { + animation: detailsIn 0.5s ease; + display: block; + } + } + } - >p { - animation: detailsIn 0.5s ease; - display: block; - } - } - } + @keyframes detailsIn { + 0% { + opacity: 0; + transform: translateY(-10px); + } - @keyframes detailsIn { - 0% { - opacity: 0; - transform: translateY(-10px); - } + 100% { + opacity: 1; + transform: none; + } + } - 100% { - opacity: 1; - transform: none; - } - } + table { + border-spacing: 0; + border: none; + border: 1px solid var(--color-outline); + border-radius: 10px; + overflow: hidden; + box-shadow: 0 0 0.5rem hsl(var(--color-concept-hsl), 0.5); - table { - border-spacing: 0; - border: none; - border: 1px solid var(--color-outline); - border-radius: 10px; - overflow: hidden; - box-shadow: 0 0 0.5rem hsl(var(--color-concept-hsl), 0.5); + thead { + background-color: rgba(0, 0, 0, 0.1); + color: #fff; + } - thead { - background-color: rgba(0, 0, 0, 0.1); - color: #fff; - } + tr { + &:nth-child(2n) { + background-color: #ffffff0d; + } + } - tr { - &:nth-child(2n) { - background-color: #ffffff0d; - } - } + td, + th { + padding: 0.5em; + border-left: 1px solid var(--color-outline); - td, - th { - padding: 0.5em; - border-left: 1px solid var(--color-outline); - - &:first-child { - border-left: none; - } - } - } -} \ No newline at end of file + &:first-child { + border-left: none; + } + } + } +} diff --git a/src/lib/page/article_page.svelte b/src/lib/page/article_page.svelte index 204ace7..7cfaa53 100644 --- a/src/lib/page/article_page.svelte +++ b/src/lib/page/article_page.svelte @@ -8,7 +8,7 @@ import type { Article } from '$lib/article'; export let data: Article; - const isUpdated = data.updated_at.getTime() != data.released_at.getTime(); + const isUpdated = data.updated_at.getTime() != data.released_at.getTime(); @@ -21,7 +21,7 @@ {#if isUpdated} {/if} - + @@ -35,20 +35,29 @@

{data.title}

- - released - {#if isUpdated}
- updated - {/if} -
- - {data.category[0].toUpperCase() + data.category.slice(1)} - {#each data.tags as tag} - {tag} - {/each} - +
+ + released + {#if isUpdated}
+ updated + {/if} +
+ + {data.category[0].toUpperCase() + data.category.slice(1)} + {#each data.tags as tag} + {tag} + {/each} + +
+
+ Author +
@{data.author}
+
@@ -91,6 +100,11 @@ height: 100%; object-fit: cover; } + .card { + position: fixed; + top: 0; + right: 0; + } main { border: 1px solid var(--line-primary); border-top: none; @@ -100,7 +114,7 @@ min-height: 100%; padding: 20px; padding-top: 100px; - max-width: 1000px; + max-width: 800px; margin: 0 auto; display: flex; flex-direction: column; @@ -110,7 +124,7 @@ font-size: 2rem; text-align: center; margin: 0; - padding: 12px 100px 12px 0; + padding: 12px; border-bottom: 1px solid rgba(255, 255, 255, 0.3); box-sizing: border-box; display: flex; @@ -120,29 +134,56 @@ .meta { display: flex; justify-content: space-between; + flex-direction: row; padding: 0 20px; - font-size: 0.8rem; - span { - opacity: 0.6; - } - a { - margin-left: 5px; - padding: 0 5px; - color: inherit; - text-decoration: none; - &:hover { - text-decoration: underline; + font-size: 1rem; + > .left { + display: flex; + flex-direction: column; + justify-content: center; + align-items: left; + span { + opacity: 0.6; } - &:first-child { - &::before { - content: '🗀 '; + a { + margin-left: 5px; + padding: 0 5px; + color: inherit; + text-decoration: none; + &:hover { + text-decoration: underline; } - &::after { - content: '|'; - margin-left: 15px; + &:first-child { + margin-left: 0; + padding-left: 0; + &::before { + content: '🗀 '; + } + &::after { + content: '|'; + margin-left: 15px; + } } } } + > .right { + display: flex; + flex-direction: row; + justify-content: right; + align-items: center; + gap: 10px; + height: 50px; + margin: 10px; + + img { + width: 50px; + height: 50px; + border-radius: 15%; + } + div { + font-size: 1rem; + } + } } } .panel { diff --git a/src/lib/server/aritcle-git.ts b/src/lib/server/aritcle-git.ts new file mode 100644 index 0000000..dc2e70a --- /dev/null +++ b/src/lib/server/aritcle-git.ts @@ -0,0 +1,15 @@ +import { simpleGit, } from 'simple-git'; +import type { SimpleGit, SimpleGitOptions } from 'simple-git'; + +console.log(process.cwd()+'/articles'); +export const gitOptions: Partial = { + baseDir: process.cwd()+'/articles', + binary: 'git', + maxConcurrentProcesses: 6, + config: [ + 'core.sshCommand=ssh -i ../key -F /dev/null' + ], +}; + +const git: SimpleGit = simpleGit(gitOptions); +export default git; \ No newline at end of file diff --git a/src/lib/server/article.ts b/src/lib/server/article.ts index 5c5ae8b..c9c283e 100644 --- a/src/lib/server/article.ts +++ b/src/lib/server/article.ts @@ -1,3 +1,4 @@ +//@ts-ignore import { compile, escapeSvelte } from "mdsvex"; import { createHighlighter } from "shiki"; import { kanagawa_dark as theme } from "$lib/kanagawa" diff --git a/src/lib/server/database/get_connection.ts b/src/lib/server/database/get_connection.ts index 8cadd60..818b226 100644 --- a/src/lib/server/database/get_connection.ts +++ b/src/lib/server/database/get_connection.ts @@ -10,10 +10,14 @@ import { } from '$env/static/private' const connectionString = `postgres://${PG_USER}:${PG_PASS}@${PG_HOST}:${PG_PORT}/${PG_DB}`; -const pool = new Pool({ connectionString }); +let pool = new Pool({ connectionString }); export const getConnection = () => pool; +export const reConnect = async () => { + pool = new Pool({ connectionString }); +} + import init_db from '$lib/server/database/init'; import PG from '$lib/server/database'; await init_db(await PG(pool)); \ No newline at end of file diff --git a/src/lib/server/database/init.ts b/src/lib/server/database/init.ts index be20422..b96b31e 100644 --- a/src/lib/server/database/init.ts +++ b/src/lib/server/database/init.ts @@ -90,10 +90,14 @@ export default async function init(db: Postgres) { }); const res = await db.query('select * from article where id = $1', [id]); - const author = gitlog.all[0].author_name; - const email = gitlog.all[0].author_email; - const released_at = new Date(gitlog.all[0].date); - const updated_at = (gitlog.latest === null) ? released_at : new Date(gitlog.latest.date); + // console.log(gitlog); + const latest = gitlog.latest!; + const oldest = gitlog.all[gitlog.all.length - 1]; + + const author = oldest.author_name; + const email = oldest.author_email; + const released_at = new Date(oldest.date); + const updated_at = new Date(latest.date); console.log(`Author: ${author} <${email}>\nReleased at: ${format(released_at)}\nUpdated at: ${format(updated_at)}`); const category = path.split('/')[3]; @@ -112,8 +116,8 @@ export default async function init(db: Postgres) { 'insert into article (id, released_at, updated_at, author, email, title, category, tags, image, publish, content) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)', [id, released_at, updated_at, author, email, title, category, tags, image, publish, content] ); - } else if (res.rows[0].updated_at < updated_at) { - // } else if (true) { + // } else if (res.rows[0].updated_at < updated_at) { + } else if (true) { console.log(`Update article: ${id}`); await db.query( 'update article set released_at = $2, updated_at = $3, author = $4, email = $5, title = $6, category = $7, tags = $8, image = $9, publish = $10, content = $11 where id = $1', diff --git a/src/routes/+page.server.ts b/src/routes/+page.server.ts index 35af34e..306e33e 100644 --- a/src/routes/+page.server.ts +++ b/src/routes/+page.server.ts @@ -1,6 +1,7 @@ import { error } from '@sveltejs/kit'; import type { PageServerLoad } from './$types'; import PG from '$lib/server/database'; +import { format } from '$lib/scripts/formatted_date'; let data: { recent: { @@ -28,7 +29,7 @@ export const load: PageServerLoad = async ({ params, locals }) => { data.recent = recent_articles.rows.map((row) => ({ title: row.title, image: row.image, - date: row.updated_at.toISOString().slice(0, 10), + date: format(row.updated_at), link: `/article/${row.category}/${row.id}`, tags: row.tags, })); diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 208e4b3..12f44c7 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -130,7 +130,7 @@ height: 100dvh; backdrop-filter: blur(2px); overflow-y: auto; - overflow-x: hidden; + overflow-x: hidden; } .controls { position: fixed; @@ -305,15 +305,15 @@ .tags { ul { display: flex; - flex-wrap: wrap; - justify-content: left; - flex-direction: row; + flex-wrap: wrap; + justify-content: left; + flex-direction: row; gap: 3px; li { font-size: 1rem; padding: 3px 5px; - border: 1px solid var(--line-primary); - border-radius: 5px; + border: 1px solid var(--line-primary); + border-radius: 5px; } } }