Skip to content

Commit

Permalink
setting
Browse files Browse the repository at this point in the history
  • Loading branch information
Slouchwind committed Jun 29, 2023
1 parent 26b49f6 commit b14a47d
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 71 deletions.
16 changes: 11 additions & 5 deletions components/contentMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,23 @@ interface ContentItem {
color?: string;
}

interface TextContentItem extends ContentItem {
interface TextCI extends ContentItem {
type: 'text';
text: string;
onClick: React.MouseEventHandler;
}

interface SeparatorContentItem extends ContentItem {
interface SeparatorCI extends ContentItem {
type: 'separator';
height: number;
}

type Content = TextContentItem | SeparatorContentItem;
interface TitleCI extends ContentItem {
type: 'title';
text: string;
}

type Content = TextCI | SeparatorCI | TitleCI;

export interface ContentMenuSet {
x: number;
Expand All @@ -27,11 +32,12 @@ export default function ContentMenu({ set }: { set: ContentMenuSet }) {
let array = set.content.map((v, i) => {
const { color = '#000' } = v;
if (v.type === 'text') return (
<div style={{ color }} onClick={v.onClick} key={i}>
<div className='text' style={{ color }} onClick={v.onClick} key={i}>
<p>{v.text}</p>
</div>
);
if (v.type === 'separator') return <hr style={{ color, height: v.height }} key={i} />;
if (v.type === 'separator') return (<div className='separator' style={{ backgroundColor: color, height: v.height }} key={i} />);
if (v.type === 'title') return (<p style={{ color }} key={i}>{v.text} </p>);
});
return (<>
{set.display && (<div id='contentMenu' style={{ left: set.x, top: set.y }}>{array}</div>)}
Expand Down
16 changes: 16 additions & 0 deletions components/i18n/config/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,21 @@ const chat = {
'zh-CN': '编辑',
'zh-TW': '編輯',
},
idConfirmTitle: {
'zh-CN': '确定删除',
'zh-TW': '確定刪除',
},
idConfirmInfo: {
'zh-CN': '确定删除与$0的聊天吗',
'zh-TW': '確定刪除於$0的聊天嗎',
},
confirm: {
'zh-CN': '确定',
'zh-TW': '確定',
},
cancel: {
'zh-CN': '取消',
'zh-TW': '取消',
},
}
export default chat;
4 changes: 2 additions & 2 deletions components/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react";
import { useSetting } from "../setting";
import { getSettingFun } from "../setting";

export type Locales = 'zh-CN' | 'zh-TW';

Expand All @@ -13,7 +13,7 @@ export function fillBlank(i18n: string, ...fills: (string | undefined)[]): strin

export function useLocale<T extends i18nContents, K extends keyof T>(i18n: T) {
const [lo, setLo] = useState('');
const { getSetting } = useSetting();
const { getSetting } = getSettingFun();
useEffect(() => setLo(getSetting().locale || window.navigator.language), []);
function locale(key: K, loc?: string) {
return (i18n as Record<K, Record<string, string>>)[key][loc || lo];
Expand Down
35 changes: 18 additions & 17 deletions components/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//Components
import Link from 'next/link';
import { SettingForm, useSetting } from '@/components/setting';
import { SettingForm, getSettingFun } from '@/components/setting';

//Styles
import styles from '@/styles/MainNode.module.scss';
Expand All @@ -9,9 +9,9 @@ import styles from '@/styles/MainNode.module.scss';
import { useRouter } from 'next/router';
import { useEffect, useState } from 'react';
import Window, { AllWindow, AllWindows, getWindowFun } from './window';
import { Locales, i18nContents, useLocale } from './i18n';
import { Locales, useLocale } from './i18n';
import main from './i18n/config/main';
import { SettingState, SettingArg } from '@/components/setting';
import { Settings, SettingArg } from '@/components/setting';

function MomoTalkIcon() {
return (
Expand All @@ -37,7 +37,7 @@ function MTBarLink({ type }: { type: string }) {
);
}

function MTStart({ animation }: { animation: SettingState['animation'] }) {
function MTStart() {
const [ani, setAni] = useState<'true' | 'false'>('false');
useEffect(() => {
const { animation } = window.sessionStorage;
Expand All @@ -48,6 +48,12 @@ function MTStart({ animation }: { animation: SettingState['animation'] }) {
}
}, []);

const [animation, setAnimation] = useState<Settings['animation']>();
const { getSetting } = getSettingFun();
useEffect(() => {
setAnimation(getSetting().animation);
}, []);

const userAni = (() => {
if (animation === 'none' || animation === undefined) return 'false';
else if (animation === 'first') return ani;
Expand All @@ -69,18 +75,13 @@ export default function MainNode({ children, onBodyClick }: {
}) {
const { lo, locale, localeType } = useLocale(main);

const { setting, setSetting } = useSetting({
locale: lo,
animation: 'first',
fileName: 'untitled',
});
const { setSetting, windowOnload } = getSettingFun();
useEffect(windowOnload, []);

const {
allWindow,
addNewWindow,
openWindow,
closeWindow,
} = getWindowFun(useState<AllWindow>({ all: [], component: {} }));
const { allWindow, addNewWindow, openWindow, closeWindow } = getWindowFun(useState<AllWindow>({
all: [],
component: {},
}));

const Setting = new Window<SettingArg>('Setting');

Expand Down Expand Up @@ -116,7 +117,7 @@ export default function MainNode({ children, onBodyClick }: {
}}
done={locale('done')}
onSubmit={data => {
setSetting(data as SettingState);
setSetting(data as Settings);
close();
}}
/>
Expand All @@ -130,7 +131,7 @@ export default function MainNode({ children, onBodyClick }: {
return (
<div id={styles.main} onClick={onBodyClick}>
<AllWindows zIndex={1099} allWindow={allWindow} />
<MTStart animation={setting.animation} />
<MTStart />
<div id={styles.MTBackground}>
<div id={styles.MTBar}>
<div id={styles.left}>
Expand Down
34 changes: 15 additions & 19 deletions components/setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,32 +77,28 @@ export function SettingForm<N extends string>({ option, done, onSubmit }: Settin
)
}

export interface SettingState {
export interface Settings {
locale?: string;
animation?: 'none' | 'first' | 'every';
fileName?: string;
}

export interface SettingArg {
setting: SettingState;
setSetting: SetStateFun<SettingState>;
setting: Settings;
setSetting: SetStateFun<Settings>;
}

export function useSetting(state?: SettingState) {
const [setting, setSetting] = getClassState(
useState<SettingState>(state || {}),
newSet => {
window.localStorage.set = JSON.stringify(newSet)
}
);
useEffect(() => {
let setting: string = window.localStorage.set;
if (setting !== undefined) {
setSetting(JSON.parse(setting));
}
}, []);
function getSetting(): SettingState {
return JSON.parse(window.localStorage.set);
export function getSettingFun(defaultSet?: Settings) {
function getSetting(): Settings {
return JSON.parse(window.localStorage.set as string);
}
return { setting, setSetting, getSetting };
function setSetting(newSet: Partial<Settings>, first?: boolean): void {
const preSet = first ? {} : getSetting();
//console.log({ preSet, newSet, localStorage: JSON.parse(localStorage.set) });
window.localStorage.set = JSON.stringify({ ...preSet, ...newSet });
}
function windowOnload() {
if (window.localStorage.set === undefined && defaultSet !== undefined) setSetting(defaultSet, true);
}
return { getSetting, setSetting, windowOnload };
}
21 changes: 15 additions & 6 deletions components/students/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@ import { getStudentInfo } from './studentsMethods';
import ImgCol from '../imgCol';

interface StudentProps {
id: number,
allInfo: studentsJson,
onClick: React.MouseEventHandler<HTMLDivElement>,
select: boolean,
id: number;
allInfo: studentsJson;
onClick: React.MouseEventHandler<HTMLDivElement>;
select: boolean;
onContentMenu?: React.MouseEventHandler<HTMLDivElement>;
}

export default function Student({ id, allInfo, onClick, select }: StudentProps) {
export default function Student({ id, allInfo, onClick, select, onContentMenu }: StudentProps) {
const info = getStudentInfo(allInfo, id);
return (
<div onClick={onClick} className={select ? 'select' : ''} title={`id:${id}`}>
<div
onClick={onClick}
onContextMenu={e => {
e.preventDefault();
onContentMenu?.(e);
}}
className={select ? 'select' : ''}
title={`id:${id}`}
>
<ImgCol
style='student'
size={60}
Expand Down
91 changes: 71 additions & 20 deletions pages/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import Window, { AllWindows, AllWindow, getWindowFun } from '@/components/window
import { SetStateFun, getClassState } from '@/components/extraReact';
import { downloadFile, uploadFile } from '@/components/loadFile';
import { ContentMenuSet } from '@/components/contentMenu';
import { SettingState, useSetting } from '@/components/setting';
import { getSettingFun } from '@/components/setting';

const StatesContext = createContext<{
allWindow: AllWindow;
Expand Down Expand Up @@ -178,7 +178,7 @@ function Loader({ type }: LoaderState) {
setChatState,
} = useContext(StatesContext);
const locale = useContext(localeContext);
const { setSetting, getSetting } = useSetting();
const { setSetting, getSetting } = getSettingFun();

return (
<img
Expand Down Expand Up @@ -264,11 +264,15 @@ interface SendMessageArg {
i?: number;
}

interface IdConfirmArg {
student: number;
textInfo: string;
studentsList?: ListState['studentsList'];
}

export default function Chat() {
const { lo, locale } = useLocale(chat);

//const { getSetting } = useSetting();

const [listState, setListState] = getClassState(useState<ListState>({
student: 0,
studentsList: [10000, 10045],
Expand Down Expand Up @@ -327,6 +331,9 @@ export default function Chat() {
const sendMessageInputRef = useRef('');
const SendMessage = new Window<SendMessageArg>('SendMessage');

//Confirm
const IdConfirm = new Window<IdConfirmArg>('IdConfirm');

useEffect(() => {
addNewWindow(IdPrompt, (zIndex, id, display, { studentsList, type }, all) => (
<IdPrompt.Component
Expand Down Expand Up @@ -429,6 +436,34 @@ export default function Chat() {
display={display}
/>
));
addNewWindow(IdConfirm, (zIndex, id, display, { student, textInfo, studentsList }, all) => (
<IdConfirm.Component
title={locale('idConfirmTitle')}
closeWindow={() => closeWindow(all, id)}
element={close => (<>
<p>{fillBlank(locale('idConfirmInfo'), textInfo)}</p>
<div>
<button
onClick={() => {
if (!studentsList?.includes(student)) {
openWindow(all, TextAlert, { title: locale('error'), elem: locale('withoutStudent') });
}
else {
const i = studentsList.indexOf(student);
studentsList.splice(i, 1);
window.localStorage.studentsList = studentsList?.join();
setListState({ studentsList });
close();
}
}}
>{locale('confirm')}</button>
<button className='cancel' onClick={() => close()}>{locale('cancel')}</button>
</div>
</>)}
zIndex={zIndex}
display={display}
/>
));
}, [lo]);

useEffect(() => {
Expand Down Expand Up @@ -463,18 +498,14 @@ export default function Chat() {
<div id={styles.title}>
<p id={styles.left}>{locale('student')}({listState.studentsList?.length})</p>
<div id={styles.right}>
<p onClick={_ => {
openWindow(allWindow.all, IdPrompt, {
studentsList: listState.studentsList,
type: '+'
});
}}>+</p>
<p onClick={_ => {
openWindow(allWindow.all, IdPrompt, {
studentsList: listState.studentsList,
type: '-'
});
}}>-</p>
{(['+', '-'] as ('+' | '-')[]).map(v => (
<p title={locale(v) + locale('student') + ''} key={v} onClick={_ => {
openWindow(allWindow.all, IdPrompt, {
studentsList: listState.studentsList,
type: v,
});
}}>{v}</p>
))}
</div>
</div>
<div style={{ height: 70 }} />
Expand All @@ -487,17 +518,37 @@ export default function Chat() {
<Repeat
variable={0}
repeat={listState.studentsList?.length}
func={v => v + 1}
components={v => {
func={i => i + 1}
components={i => {
if (!listState.studentsJson || !listState.studentsList) return;
const id = listState.studentsList[v];
const id = listState.studentsList[i];
return (
<Student
id={id}
allInfo={listState.studentsJson.data}
key={id}
onClick={() => setListState({ student: id })}
select={listState.student === id}
onContentMenu={e => {
const info = getStudentInfo(listState.studentsJson?.data as studentsJson, id);
setContentMenu({
x: e.clientX,
y: e.clientY,
content: [
{ type: 'title', text: `${info.schale?.Name} id: ${id}` },
{ type: 'separator', color: '#ccc', height: 1 },
{
type: 'text', text: locale('delete'), onClick() {
openWindow(allWindow.all, IdConfirm, {
student: id,
textInfo: info.schale?.Name as string,
studentsList: listState.studentsList,
});
}
},
],
display: true,
});
}}
/>
);
}}
Expand Down
Loading

1 comment on commit b14a47d

@vercel
Copy link

@vercel vercel bot commented on b14a47d Jun 29, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.