Skip to content

Commit

Permalink
refactor: ♻️ 实现 toast
Browse files Browse the repository at this point in the history
  • Loading branch information
hymbz committed May 26, 2023
1 parent 09fc1ea commit d274cba
Show file tree
Hide file tree
Showing 24 changed files with 498 additions and 201 deletions.
5 changes: 4 additions & 1 deletion .stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ module.exports = {

// 允许 css 变量使用任意命名方式
'custom-property-pattern': null,
// 允许任意类型的类名命名方式
// 允许任意类型的命名方式
'selector-class-pattern': null,
'keyframes-name-pattern': null,
// 允许重复的 css 动画帧
'keyframe-block-no-duplicate-selectors': null,

// 防止使用低性能的动画和过度属性
'plugin/no-low-performance-animation-properties': true,
Expand Down
1 change: 1 addition & 0 deletions docs/Dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

- 测试平板上的使用
- 300 自动签到功能在首次签到成功时报错
- dmzj 隐藏漫画增加上下话切换

卷轴模式下图片的宽度应该要能简单调整,加设置项太麻烦,应该直接使用缩放功能来实现。目前已经可以在保持缩放的状态下滚动了,但现在使用的缩放库有几个问题
1. 没办法在缩小后保持图片居中
Expand Down
1 change: 1 addition & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
<style type="text/css">
html {
background-color: black;
color: white;
}
#root {
height: 100vh;
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
"panzoom": "^9.4.3",
"solid-element": "^1.7.0",
"solid-js": "^1.7.3",
"solid-toast": "^0.5.0",
"throttle-debounce": "^5.0.0"
},
"devDependencies": {
Expand Down
3 changes: 0 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,19 +71,20 @@ export const meta = {
'idmzj.com',
'exhentai.org',
'e-hentai.org',
'hath.network',
'nhentai.net',
'hypergryph.com',
'mangabz.com',
'copymanga.site',
'copymanga.info',
'copymanga.net',
'copymanga.org',
'copymanga.com',
'self',
'*',
],
grant: [
'GM_addElement',
'GM_getResourceText',
'GM_xmlhttpRequest',
'GM.addValueChangeListener',
'GM.removeValueChangeListener',
'GM.getResourceText',
'GM.addStyle',
'GM.getValue',
Expand Down Expand Up @@ -122,7 +123,7 @@ const metaHeader = (() => {
}
})
.join('\n');
return ['// ==UserScript==', metaStr, '// ==/UserScript=='].join('\n');
return `// ==UserScript==\n${metaStr}\n// ==/UserScript==\n\n`;
})();

export const buildOptions = (
Expand Down Expand Up @@ -174,8 +175,6 @@ export const buildOptions = (
strict: false,
generatedCode: 'es2015',
extend: true,
// 为脚本加上油猴的注释
intro: isUserScript ? metaHeader : undefined,
plugins: [
{
name: 'selfPlugin',
Expand Down Expand Up @@ -225,6 +224,9 @@ export const buildOptions = (
break;
}

// 为脚本加上油猴的注释
if (isUserScript) newCode = metaHeader + newCode;

return newCode;
},
},
Expand Down
1 change: 1 addition & 0 deletions src/components/Manga/components/ComicImg.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
/* 隐藏滚动条但不影响滚动 */
scrollbar-width: none;
height: 100%;
outline: none;

/* 隐藏滚动条但不影响滚动 */
&::-webkit-scrollbar {
Expand Down
91 changes: 91 additions & 0 deletions src/components/Toast/ToastItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import MdCheckCircle from '@material-design-icons/svg/round/check_circle.svg';
import MdWarning from '@material-design-icons/svg/round/warning.svg';
import MdError from '@material-design-icons/svg/round/error.svg';
import MdInfo from '@material-design-icons/svg/round/info.svg';

import type { Component } from 'solid-js';
import { createEffect, Show } from 'solid-js';
import { Dynamic } from 'solid-js/web';
import { setState } from './helper';

import type { Toast } from '.';
import { toast } from './toast';

import classes from './index.module.css';

const iconMap = {
info: MdInfo,
success: MdCheckCircle,
warn: MdWarning,
error: MdError,
};

const colorMap = {
info: '#3a97d7',
success: '#23bb35',
warn: '#f0c53e',
error: '#e45042',
custom: '#1f2936',
};

/** 删除 toast */
const dismissToast = (id: string) =>
setState((state) => {
state.map[id].onDismiss?.({ ...state.map[id] });
const i = state.list.findIndex((t) => t === id);
if (i !== -1) state.list.splice(i, 1);
Reflect.deleteProperty(state.map, id);
});

/** 重置 toast 的 update 属性 */
const resetToastUpdate = (id: string) =>
setState((state) => {
Reflect.deleteProperty(state.map[id], 'update');
});

export const ToastItem: Component<Toast> = (props) => {
const dismiss = (e: Event) => {
e.stopPropagation();
toast.dismiss(props.id);
};

// 在退出动画结束后才真的删除
const handleAnimationEnd = () => {
if (!props.exit) return;
dismissToast(props.id);
};

let scheduleRef: HTMLDivElement;
createEffect(() => {
if (!props.update) return;

resetToastUpdate(props.id);
scheduleRef.getAnimations().forEach((animation) => {
animation.cancel();
animation.play();
});
});

return (
<div
class={classes.item}
style={{ '--theme': colorMap[props.type] }}
data-exit={props.exit}
onClick={dismiss}
onAnimationEnd={handleAnimationEnd}
>
<Dynamic component={iconMap[props.type]} />
<div class={classes.msg}>
{typeof props.msg === 'string' ? props.msg : <props.msg />}
</div>
<Show when={props.duration !== Infinity}>
<div
ref={scheduleRef!}
class={classes.schedule}
style={{ 'animation-duration': `${props.duration}ms` }}
onAnimationEnd={dismiss}
/>
</Show>
</div>
);
};
29 changes: 29 additions & 0 deletions src/components/Toast/Toaster.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { Component } from 'solid-js';
import { For, createSignal, onCleanup, onMount } from 'solid-js';
import { store } from './helper';
import { ToastItem } from './ToastItem';

import classes from './index.module.css';

export const Toaster: Component = () => {
const [visible, setVisible] = createSignal(
document.visibilityState === 'visible',
);

onMount(() => {
const handleVisibilityChange = () => {
console.log(document.visibilityState);
setVisible(document.visibilityState === 'visible');
};
document.addEventListener('visibilitychange', handleVisibilityChange);
onCleanup(() =>
document.removeEventListener('visibilitychange', handleVisibilityChange),
);
});

return (
<div class={classes.root} data-paused={visible() ? undefined : ''}>
<For each={store.list}>{(id) => <ToastItem {...store.map[id]} />}</For>
</div>
);
};
50 changes: 50 additions & 0 deletions src/components/Toast/display.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* 用于测试时显示组件
*/

import { toast } from '.';
import { Toaster } from './Toaster';

export default function Display() {
const duration = 1000 * 3;

return (
<div style={{ height: '100vh' }}>
<button onClick={() => toast('加载图片中,请稍候', { duration })}>
文字
</button>

<button
onClick={() => toast(() => <div>加载图片中,请稍候</div>, { duration })}
>
JSX
</button>

<button onClick={() => toast.success('加载图片中,请稍候', { duration })}>
success
</button>
<button onClick={() => toast.warn('加载图片中,请稍候', { duration })}>
warn
</button>
<button onClick={() => toast.error('加载图片中,请稍候', { duration })}>
error
</button>

<button
onClick={() =>
toast.error('加载图片中,请稍候', { duration: Infinity })
}
>
永久显示
</button>

<button
onClick={() => toast.error('加载图片中,请稍候', { duration, id: '1' })}
>
更新
</button>

<Toaster />
</div>
);
}
21 changes: 21 additions & 0 deletions src/components/Toast/helper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { createStore, produce } from 'solid-js/store';
import type { Toast } from '.';

const [_state, _setState] = createStore({
list: [] as Toast['id'][],
map: {} as Record<Toast['id'], Toast>,
});
export type State = typeof _state;

export const setState = (fn: (state: State) => void) => _setState(produce(fn));

// eslint-disable-next-line solid/reactivity
export const store: Readonly<State> = _state;

export const creatId = (): string => {
let id = `${Date.now()}`;
while (Reflect.has(store.map, id)) {
id += '_';
}
return id;
};
Loading

0 comments on commit d274cba

Please sign in to comment.