Skip to content

Commit

Permalink
Merge pull request #81 from mebtte/beta
Browse files Browse the repository at this point in the history
improve style
  • Loading branch information
MEBTTE committed Jul 27, 2023
2 parents 57d7bda + 971c502 commit b0d5aaf
Show file tree
Hide file tree
Showing 32 changed files with 448 additions and 229 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
"-r",
"${workspaceFolder}/node_modules/tsconfig-paths/register"
],
"args": ["${workspaceFolder}/apps/server/dev.ts"],
"args": ["${workspaceFolder}/apps/cli/dev_server.ts"],
"cwd": "${workspaceFolder}",
"env": {
"TS_NODE_PROJECT": "${workspaceFolder}/apps/server/tsconfig.json"
"TS_NODE_PROJECT": "${workspaceFolder}/apps/cli/tsconfig.json"
}
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,11 @@ import generateRandomInteger from '#/utils/generate_random_integer';
import { REMARK_MAX_LENGTH } from '#/constants/user';
import { sendEmail } from '@/platform/email';
import { getUserByEmail } from '@/db/user';
import { UserProperty } from '@/constants/db_definition';
import { USER_TABLE_NAME, UserProperty } from '@/constants/db_definition';
import capitalize from '#/utils/capitalize';
import upperCaseFirstLetter from '#/utils/upper_case_first_letter';
import { Context } from '../constants';

const generateEmailHtml = ({ accessOrigin }: { accessOrigin: string }) => `Hi,
<br>
<br>
已成功为您创建账号, 现在可以使用当前邮箱登录到「<a href="${accessOrigin}">知了</a>」.
<br>
如果使用中有任何问题或者建议, 可以通过 <a href="https://github.com/mebtte/cicada">Issue</a> 进行反馈.
<br>
<br>
知了
<br>
${day(new Date()).format('YYYY-MM-DD HH:mm')}`;

export default async (ctx: Context) => {
const {
email,
Expand Down Expand Up @@ -49,15 +39,32 @@ export default async (ctx: Context) => {

await sendEmail({
to: email,
title: `欢迎使用${ctx.t('cicada')}`,
html: generateEmailHtml({ accessOrigin }),
fromName: ctx.t('cicada'),
title: upperCaseFirstLetter(
ctx.t('welcome_to', capitalize(ctx.t('cicada'))),
),
html: `
Hi,
<br>
<br>
${upperCaseFirstLetter(
ctx.t(
'new_user_email_content',
`<a href="${accessOrigin}">${ctx.t('cicada')}</a>`,
),
)}
<br>
<br>
${capitalize(ctx.t('cicada'))}
<br>
${day(new Date()).format('YYYY-MM-DD HH:mm')}
`,
fromName: capitalize(ctx.t('cicada')),
});

const id = generateRandomInteger(1_0000, 1000_0000).toString();
await getDB().run(
`
INSERT INTO user ( id, email, nickname, joinTimestamp, remark )
INSERT INTO ${USER_TABLE_NAME} ( ${UserProperty.ID}, ${UserProperty.EMAIL}, ${UserProperty.NICKNAME}, ${UserProperty.JOIN_TIMESTAMP}, ${UserProperty.REMARK} )
VALUES ( ?, ?, ?, ?, ? )
`,
[id, email, id, Date.now(), remark],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import generateRandomInteger from '#/utils/generate_random_integer';
import { sendEmail } from '@/platform/email';
import day from '#/utils/day';
import { getConfig } from '@/config';
import capitalize from '#/utils/capitalize';
import upperCaseFirstLetter from '#/utils/upper_case_first_letter';
import { User, UserProperty, USER_TABLE_NAME } from '@/constants/db_definition';
import { LOGIN_CODE_TTL } from '../../../../constants';
import { Context } from '../constants';

Expand Down Expand Up @@ -40,13 +43,15 @@ export default async (ctx: Context) => {
return ctx.except(ExceptionCode.CAPTCHA_ERROR);
}

const user = await getDB().get<{ id: string; nickname: string }>(
const user = await getDB().get<
Pick<User, UserProperty.ID | UserProperty.NICKNAME>
>(
`
SELECT
id,
nickname
FROM user
WHERE email = ?
${UserProperty.ID},
${UserProperty.NICKNAME}
FROM ${USER_TABLE_NAME}
WHERE ${UserProperty.EMAIL} = ?
`,
[email],
);
Expand All @@ -70,26 +75,29 @@ export default async (ctx: Context) => {
if (getConfig().mode === 'development') {
// eslint-disable-next-line no-console
console.log(`\n--- user id: ${user.id}, login code: ${code} ---\n`);
} else {
await sendEmail({
to: email,
title: `「${ctx.t('cicada')}」登录验证码`,
html: `
}
await sendEmail({
to: email,
title: capitalize(`${ctx.t('cicada')} ${ctx.t('login_code')}`),
html: `
Hi, 「${encode(user.nickname)}」,
<br />
<br />
你刚刚尝试登录, 本次登录验证码是「<code>${code}</code>」, ${
LOGIN_CODE_TTL / 1000 / 60
} 分钟内有效.
${upperCaseFirstLetter(
ctx.t(
'login_code_email_content',
`<code>${code}</code>`,
(LOGIN_CODE_TTL / 1000 / 60).toString(),
),
)}
<br />
<br />
${ctx.t('cicada')}
${capitalize(ctx.t('cicada'))}
<br />
${day().format('YYYY-MM-DD HH:mm:ss')}
`,
fromName: ctx.t('cicada'),
});
}
fromName: capitalize(ctx.t('cicada')),
});

/**
* 如果 Promise.all 发送邮件和写入数据库
Expand Down
5 changes: 5 additions & 0 deletions apps/cli/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,9 @@ export default {
'no permission to delete musicbill shared user',
shared_musicbill_invitation_not_existed:
'shared_musicbill_invitation_not_existed',
login_code: 'login code',
login_code_email_content:
'your login code is %s1, you can use it within %s2 minutes.',
welcome_to: 'welcome to %s1',
new_user_email_content: 'now you can use current email to login on %s1.',
};
6 changes: 4 additions & 2 deletions apps/cli/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ import { Language } from '#/constants';
import { Key } from './constants';
import en from './en';
import zhHans from './zh_hans';
import ja from './ja';

const LANGUAGE_MAP: Record<Language, typeof en> = {
[Language.EN]: en,
[Language.ZH_HANS]: zhHans,
[Language.JA]: ja,
};

export function t(key: Key, language: Language, ...args: string[]) {
const value = LANGUAGE_MAP[language][key];
let value = LANGUAGE_MAP[language][key];

if (args.length) {
for (let i = 0; i < args.length; i += 1) {
value.replace(`%s${i + 1}`, args[i]);
value = value.replace(`%s${i + 1}`, args[i]);
}
}

Expand Down
10 changes: 10 additions & 0 deletions apps/cli/src/i18n/ja.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Key } from './constants';
import en from './en';

const ja: {
[key in Key]: string;
} = {
...en,
};

export default ja;
5 changes: 5 additions & 0 deletions apps/cli/src/i18n/zh_hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ const zhHans: {
repeated_shared_musicbill_invitation: '重复的共享乐单邀请',
no_permission_to_delete_musicbill_shared_user: '没有权限删除共享乐单用户',
shared_musicbill_invitation_not_existed: '共享乐单邀请不存在',
login_code: '登录验证码',
login_code_email_content:
'你刚刚尝试登录, 本次登录验证码是 %s1, %s2 分钟内有效.',
welcome_to: '欢迎使用%s1',
new_user_email_content: '你可以使用当前邮箱登录%s1了.',
};

export default zhHans;
11 changes: 9 additions & 2 deletions apps/pwa/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default {
please_enter_valid_email: 'please enter valid email',
captcha: 'captcha',
get_login_code: 'get login code',
login_code_has_emailed: 'login code has emailed',
login_code_emailed: 'login code emailed',
change_language_question:
'changing language will reload application, continue ?',
relative_volume: 'relative volume',
Expand All @@ -24,12 +24,19 @@ export default {
musicbill: 'musicbill',
user_management: 'user management',
logout: 'logout',
logout_question: 'Are you sure to logout ?',
logout_question: 'are you sure to logout ?',
search: 'search',
shared_musicbill_invitation: 'shared musicbill invitation',
public_musicbill_collection: 'public musicbill collection',
previous_step: 'previous step',
login_code: 'login code',
please_enter_login_code: 'please enter login code',
welcome_back: 'welcome back',
create_at: 'create at',
no_music_in_musicbill: 'no music in musicbill',
find_in_musicbill: 'find in musicbill',
user_created: 'user created',
create_user: 'create user',
remark: 'remark',
create: 'create',
};
9 changes: 7 additions & 2 deletions apps/pwa/src/i18n/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ switch (setting.get().language) {
({ default: translation } = await import('./zh_hans'));
break;
}
case Language.JA: {
({ default: translation } = await import('./ja'));
break;
}
default: {
({ default: translation } = await import('./en'));
}
}

export function t(key: Key, ...args: string[]) {
const value = translation[key];
let value = translation[key];

if (args.length) {
for (let i = 0; i < args.length; i += 1) {
value.replace(`%s${i + 1}`, args[i]);
value = value.replace(`%s${i + 1}`, args[i]);
}
}

Expand All @@ -33,6 +37,7 @@ export const LANGUAGE_MAP: Record<
> = {
[Language.EN]: { label: 'english' },
[Language.ZH_HANS]: { label: '简体中文' },
[Language.JA]: { label: '日本語' },
};

export { Key };
10 changes: 10 additions & 0 deletions apps/pwa/src/i18n/ja.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Key } from './constants';
import en from './en';

const ja: {
[key in Key]: string;
} = {
...en,
};

export default ja;
9 changes: 8 additions & 1 deletion apps/pwa/src/i18n/zh_hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const zhCN: {
please_enter_valid_email: '请输入合法的邮箱',
captcha: '验证码',
get_login_code: '获取登录验证码',
login_code_has_emailed: '登录验证码已经发送到邮箱',
login_code_emailed: '登录验证码已发送到邮箱',
change_language_question: '更换语言将会重新加载应用, 是否继续?',
relative_volume: '相对音量',
music_play_record_short: '播放记录',
Expand All @@ -34,6 +34,13 @@ const zhCN: {
login_code: '登录验证码',
please_enter_login_code: '请输入登录验证码',
welcome_back: '欢迎回来',
create_at: '创建于',
no_music_in_musicbill: '乐单暂无音乐',
find_in_musicbill: '乐单内查找',
user_created: '用户已创建',
create_user: '创建用户',
remark: '备注',
create: '创建',
};

export default zhCN;
2 changes: 1 addition & 1 deletion apps/pwa/src/pages/login/email_panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function EmailPanel({ toNext }: { toNext: (email: string) => void }) {
captchaId,
captchaValue,
});
notice.info(t('login_code_has_emailed'));
notice.info(t('login_code_emailed'));
toNext(email);
} catch (error) {
logger.error(error, 'Failed to get login code');
Expand Down
3 changes: 2 additions & 1 deletion apps/pwa/src/pages/login/user_panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Query } from '@/constants';
import Cover, { Shape } from '@/components/cover';
import Slider from '@/components/slider';
import { t } from '@/i18n';
import upperCaseFirstLetter from '#/utils/upper_case_first_letter';
import Paper from './paper';
import Logo from './logo';

Expand Down Expand Up @@ -72,7 +73,7 @@ function Profile({ profile }: { profile: ProfileType }) {
shape={Shape.CIRCLE}
/>
<div className="text">
🎉 {t('welcome_back')},{' '}
🎉 {upperCaseFirstLetter(t('welcome_back'))},{' '}
{profile.nickname.length > NICKNAME_MAX_LENGTH
? `${profile.nickname.slice(0, NICKNAME_MAX_LENGTH)}...`
: profile.nickname}
Expand Down
4 changes: 3 additions & 1 deletion apps/pwa/src/pages/player/pages/musicbill/filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Input from '@/components/input';
import { useEffect, useState } from 'react';
import useNavigate from '@/utils/use_navigate';
import { Query } from '@/constants';
import { t } from '@/i18n';
import upperCaseFirstLetter from '#/utils/upper_case_first_letter';
import { FILTER_HEIGHT } from './constants';

const Style = styled.div`
Expand Down Expand Up @@ -49,7 +51,7 @@ function Filter() {
inputProps={{
value: keyword,
onChange: (event) => setKeyword(event.target.value),
placeholder: '乐单内查找',
placeholder: upperCaseFirstLetter(t('find_in_musicbill')),
}}
/>
</Style>
Expand Down
6 changes: 5 additions & 1 deletion apps/pwa/src/pages/player/pages/musicbill/info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import styled from 'styled-components';
import day from '#/utils/day';
import { CSSVariable } from '@/global_style';
import getResizedImage from '@/server/asset/get_resized_image';
import { t } from '@/i18n';
import upperCaseFirstLetter from '@/style/upper_case_first_letter';
import { Musicbill } from '../../constants';
import { INFO_HEIGHT } from './constants';
import Operation from './operation';
Expand Down Expand Up @@ -35,6 +37,7 @@ const Style = styled.div`
> .create-time {
font-size: 12px;
color: ${CSSVariable.TEXT_COLOR_SECONDARY};
${upperCaseFirstLetter}
}
}
`;
Expand All @@ -51,7 +54,8 @@ function Info({ musicbill }: { musicbill: Musicbill }) {
<div className="info">
<div className="name">{musicbill.name}</div>
<div className="create-time">
创建于 {day(musicbill.createTimestamp).format('YYYY-MM-DD HH:mm')}
{t('create_at')}{' '}
{day(musicbill.createTimestamp).format('YYYY-MM-DD HH:mm')}
</div>
<Operation musicbill={musicbill} />
</div>
Expand Down
4 changes: 3 additions & 1 deletion apps/pwa/src/pages/player/pages/musicbill/operation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
} from 'react-icons/md';
import { RequestStatus } from '@/constants';
import notice from '@/utils/notice';
import { t } from '@/i18n';
import upperCaseFirstLetter from '#/utils/upper_case_first_letter';
import playerEventemitter, {
EventType as PlayerEventType,
} from '../../eventemitter';
Expand All @@ -34,7 +36,7 @@ function Operation({ musicbill }: { musicbill: Musicbill }) {
musicList,
},
)
: notice.error('乐单暂无音乐')
: notice.error(upperCaseFirstLetter(t('no_music_in_musicbill')))
}
>
<MdPlaylistAdd />
Expand Down
Loading

0 comments on commit b0d5aaf

Please sign in to comment.