Skip to content

Commit 1ddef1f

Browse files
committed
feat(monkey): optimize copymanga detail layout and split storage modules
1 parent b720bb5 commit 1ddef1f

22 files changed

Lines changed: 612 additions & 390 deletions

File tree

‎etc/build/monkey.const.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export const bannerOrderMap = {
1212
'icon64',
1313
'icon64URL',
1414
'version',
15-
'author'
15+
'author',
1616
],
1717
tail: [
1818
'homepage',
@@ -23,7 +23,7 @@ export const bannerOrderMap = {
2323
'downloadURL',
2424
'updateURL',
2525
'run-at',
26-
'grant'
26+
'grant',
2727
],
2828
}
2929

‎src/monkey/copymanga-enhance/scripts/detail/newPage/component/App/style.css‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
:root {
22
--header-height: 30px;
33
--body-height: calc(100dvh - var(--header-height));
4+
--image-group-padding: calc(var(--body-height) / 6 * 5);
45
}
56

67
#app {

‎src/monkey/copymanga-enhance/scripts/detail/newPage/component/AppBody/index.ts‎

Lines changed: 48 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,50 @@
11
import GM_addStyle from "../../../../../../polyfill/GM_addStyle";
22
import cc from 'classcat'
3-
import { ACTION_GRID_MAP, DirectionMode, PageType } from "../../constant";
3+
import { ACTION_GRID_MAP, DirectionMode } from "../../constant";
44
import useDirectionMode from "../../hooks/useDirectionMode";
5-
import useImageInfoMap from "../../hooks/useImageInfoMap";
6-
import useImageList from "../../hooks/useImageList";
7-
import useWhitePage from "../../hooks/useWhitePage";
8-
import { defineComponent, onMounted, unref, h, watch, ref, computed } from "../../vue";
9-
import Image from "../Image";
5+
import { defineComponent, onMounted, unref, h, ref, watch } from "../../vue";
106
import css from './style.css'
11-
import WhitePage from '../WhitePage';
12-
import flow from "../../../../../../utils/flow";
137
import useMouseGrid from "../../hooks/useMouseGrid";
14-
import ImageGroup, { ImageItem } from "../ImageGroup";
8+
import ImageGroup from "../ImageGroup";
159
import useTtbColumn from "../../hooks/useTtbColumn";
10+
import useImageList from "../../hooks/useImageList";
11+
import useImageWidth from "../../hooks/useImageWidth";
12+
import debounce from "../../../../utils/debounce";
13+
import { useWindowSize } from "../../hooks/useWindowSize";
1614

1715
export default defineComponent({
1816
setup () {
19-
const [whitePageRef] = useWhitePage()
20-
const [directionModeRef] = useDirectionMode()
21-
const imageListRef = useImageList()
22-
const infoMapRef = useImageInfoMap()
2317
onMounted(() => {
2418
GM_addStyle(css)
25-
refresh()
2619
})
27-
watch(whitePageRef, () => refresh())
28-
watch(directionModeRef, () => refresh())
29-
watch(imageListRef, () => refresh())
30-
watch(infoMapRef, () => refresh())
31-
const onLoaded = () => {
32-
refresh()
33-
}
34-
const parseImages = (urls: readonly string[] = []): ImageItem[] => {
35-
const infoMap = unref(infoMapRef)
36-
return urls
37-
.map((src, index) => {
38-
const info = infoMap[index]
39-
const pageType: PageType = info && info.type === PageType.LANDSCAPE ? PageType.LANDSCAPE : PageType.PORTRAIT
40-
return {
41-
component: Image,
42-
props: {
43-
src,
44-
onLoaded,
45-
key: `image-${index}`,
46-
pageType,
47-
},
48-
}
49-
})
50-
}
51-
const addFirstWhitePage = (list: ImageItem[]): ImageItem[] => {
52-
if (list.length === 0) return list
53-
if (!unref(whitePageRef)) return list
54-
if (![DirectionMode.RTL, DirectionMode.LTR].includes(unref(directionModeRef))) return list
55-
56-
let anchorIndex = -1
57-
for (let index = 0; index < list.length; index++) {
58-
const { props } = list[index]
59-
if (props.pageType === PageType.LANDSCAPE) {
60-
anchorIndex = -1
61-
continue
62-
}
63-
if (anchorIndex === -1) {
64-
anchorIndex = index
65-
continue
66-
}
67-
if (index - anchorIndex > 2) {
68-
list.splice(anchorIndex, 0, {
69-
component: WhitePage,
70-
props: { key: `white-page-${anchorIndex}`, class: 'manual', pageType: PageType.PORTRAIT },
71-
})
72-
break
73-
}
74-
}
75-
return list
76-
}
77-
const injectWhitePages = (list: ImageItem[]): ImageItem[] => {
78-
if (list.length === 0) return list
79-
if (![DirectionMode.RTL, DirectionMode.LTR].includes(unref(directionModeRef))) return list
20+
const [imagesRef] = useImageList()
21+
const [directionModeRef] = useDirectionMode()
22+
const [mouseGridRef] = useMouseGrid()
23+
const [imageWidthRef] = useImageWidth()
24+
const [ttbColumnRef] = useTtbColumn()
25+
const { width: windowWidthRef } = useWindowSize()
8026

81-
const tempList: ImageItem[][] = []
82-
for (let index = 0; index < list.length; index++) {
83-
const { props: { pageType } } = list[index]
84-
let lastGroupPageType = tempList.length > 0 ? tempList[tempList.length - 1][0].props.pageType : null
85-
if (pageType !== lastGroupPageType) {
86-
tempList.push([])
87-
}
88-
tempList[tempList.length - 1].push(list[index])
89-
}
90-
for (let groupIndex = 0; groupIndex < tempList.length; groupIndex++) {
91-
const group = tempList[groupIndex]
92-
if (group[0].props.pageType === PageType.LANDSCAPE) continue
93-
if (group.length % 2 === 0) continue
94-
group.push({
95-
component: WhitePage,
96-
props: { key: `white-page-group-${groupIndex}`, class: 'auto', pageType: PageType.PORTRAIT },
97-
})
98-
}
99-
if (
100-
tempList[tempList.length - 1][0].props.pageType === PageType.PORTRAIT &&
101-
tempList[tempList.length - 1].length % 4 !== 0
102-
) {
103-
const groupIndex = tempList.length - 1
104-
const group = tempList[groupIndex]
105-
Array.from({ length: 4 - (group.length % 4) }).forEach((_, index) => {
106-
group.push({
107-
component: WhitePage,
108-
props: { key: `white-page-group-${groupIndex + index}-end`, class: 'auto end', pageType: PageType.PORTRAIT },
109-
})
110-
})
27+
const imageGroupHeightRef = ref(0)
28+
const imageGroupRef = ref<InstanceType<typeof ImageGroup> | null>(null)
29+
const refreshImageGroupHeight = debounce(() => {
30+
const list = Array.from<HTMLElement>(unref(imageGroupRef)?.$el.children ?? [])
31+
const height = list.reduce((acc, child) => acc + child.clientHeight, 0)
32+
imageGroupHeightRef.value = height
33+
}, 50)
34+
watch(
35+
[
36+
imagesRef,
37+
directionModeRef,
38+
ttbColumnRef,
39+
imageGroupRef,
40+
imageWidthRef,
41+
windowWidthRef,
42+
], () => {
43+
if (DirectionMode.TTB !== unref(directionModeRef)) return
44+
refreshImageGroupHeight()
11145
}
112-
return tempList.flat();
113-
}
114-
const injectDataIndex = (list: ImageItem[]): ImageItem[] => {
115-
let portraitCount = 0
116-
return list.map((item, index) => {
117-
let targetIndex = index + 1
118-
let side = 'A'
119-
if (item.props.pageType === PageType.LANDSCAPE) {
120-
portraitCount = 0
121-
side = 'A'
122-
} else {
123-
portraitCount++
124-
if (DirectionMode.RTL === unref(directionModeRef)) {
125-
if (portraitCount % 2 === 0) {
126-
targetIndex -= 1
127-
} else {
128-
targetIndex += 1
129-
}
130-
side = portraitCount % 2 === 1 ? 'R' : 'L'
131-
}
132-
if (DirectionMode.LTR === unref(directionModeRef)) {
133-
side = portraitCount % 2 === 1 ? 'L' : 'R'
134-
}
135-
}
136-
return ({
137-
...item,
138-
props: {
139-
...item.props,
140-
'data-index': targetIndex,
141-
'data-side': side,
142-
},
143-
})
144-
})
145-
}
146-
const imagesRef = ref<ImageItem[]>([])
147-
const refresh = () => {
148-
const list = flow(
149-
unref(imageListRef),
150-
parseImages,
151-
addFirstWhitePage,
152-
injectWhitePages,
153-
injectDataIndex
154-
)
155-
imagesRef.value = list
156-
}
46+
)
15747

158-
const [mouseGridRef] = useMouseGrid()
159-
const [ttbColumnRef] = useTtbColumn()
160-
const avgImageHalfHeightRef = computed(() => {
161-
const totalHeight = infoMapRef.value.map((info) => info ? info.height : 0)
162-
.reduce((a, b) => a + b, 0)
163-
const total = unref(imageListRef).length
164-
return Math.ceil((total > 0 ? totalHeight / total : 0) / 2)
165-
})
16648
return () => h(
16749
'div',
16850
{
@@ -178,50 +60,56 @@ export default defineComponent({
17860
{
17961
class: cc([
18062
'direction-wrapper',
63+
'max-h-(--body-height)',
18164
'flex flex-row flex-wrap',
65+
'overflow-x-hidden overflow-y-auto',
18266
]),
18367
},
18468
[
18569
h(
18670
ImageGroup,
18771
{
18872
class: cc([
73+
'ltr:hidden rtl:hidden',
74+
'overflow-hidden',
18975
{
190-
'w-dvw': DirectionMode.TTB !== unref(directionModeRef),
191-
'basic-[50%]': DirectionMode.TTB === unref(directionModeRef) && unref(ttbColumnRef) === 2,
192-
'basic-[33%]': DirectionMode.TTB === unref(directionModeRef) && unref(ttbColumnRef) === 3,
193-
},
76+
'hidden': unref(ttbColumnRef) === 1 || unref(ttbColumnRef) === 2,
77+
'basic-[33%]': unref(ttbColumnRef) === 3,
78+
}
19479
]),
19580
images: unref(imagesRef),
81+
style: `height: ${unref(imageGroupHeightRef)}px`,
19682
},
19783
),
19884
h(
19985
ImageGroup,
20086
{
20187
class: cc([
20288
'ltr:hidden rtl:hidden',
89+
'overflow-hidden',
20390
{
20491
'hidden': unref(ttbColumnRef) === 1,
20592
'basic-[50%]': unref(ttbColumnRef) === 2,
20693
'basic-[33%]': unref(ttbColumnRef) === 3,
20794
},
20895
]),
209-
style: `margin-top: -${avgImageHalfHeightRef.value}px;`,
21096
images: unref(imagesRef),
97+
style: `height: ${unref(imageGroupHeightRef)}px`,
21198
},
21299
),
213100
h(
214101
ImageGroup,
215102
{
216103
class: cc([
217-
'ltr:hidden rtl:hidden',
218104
{
219-
'hidden': unref(ttbColumnRef) === 1 || unref(ttbColumnRef) === 2,
220-
'basic-[33%]': unref(ttbColumnRef) === 3,
221-
}
105+
'w-dvw': DirectionMode.TTB !== unref(directionModeRef),
106+
'flex': unref(ttbColumnRef) === 1,
107+
'basic-[50%]': DirectionMode.TTB === unref(directionModeRef) && unref(ttbColumnRef) === 2,
108+
'basic-[33%]': DirectionMode.TTB === unref(directionModeRef) && unref(ttbColumnRef) === 3,
109+
},
222110
]),
223-
style: `margin-top: -${avgImageHalfHeightRef.value * 2}px;`,
224111
images: unref(imagesRef),
112+
ref: imageGroupRef,
225113
},
226114
),
227115
],

‎src/monkey/copymanga-enhance/scripts/detail/newPage/component/AppBody/style.css‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
.direction-wrapper {
2-
max-height: var(--body-height);
3-
overflow-y: scroll;
1+
.direction-wrapper > *:nth-child(1) {
2+
--image-group-padding-1: calc(var(--image-group-padding) * 2);
3+
padding-top: var(--image-group-padding-1);
44
}
55

6-
.wrapper {
7-
flex-basis: 100%;
8-
justify-content: center;
6+
.direction-wrapper > *:nth-child(2) {
7+
--image-group-padding-2: calc(var(--image-group-padding) * 1);
8+
padding-top: var(--image-group-padding-2);
99
}
1010

1111
/* #region 单列时 */

‎src/monkey/copymanga-enhance/scripts/detail/newPage/component/AppHeader/index.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import GM_addStyle from "../../../../../../polyfill/GM_addStyle";
33
import { DirectionMode } from "../../constant";
44
import useDirectionMode from "../../hooks/useDirectionMode";
55
import useImageInfoMap from "../../hooks/useImageInfoMap";
6-
import useImageList from "../../hooks/useImageList";
6+
import useRawImageList from "../../hooks/useRawImageList";
77
import usePageInfo from "../../hooks/usePageInfo";
88
import useWhitePage from "../../hooks/useWhitePage";
99
import { defineComponent, onMounted, unref, computed, h, Fragment } from "../../vue";
@@ -22,10 +22,10 @@ export default defineComponent({
2222
const titleUrlRef = computed(() => unref(pageInfoRef).menuUrl)
2323
const prevUrlRef = computed(() => unref(pageInfoRef).prevUrl)
2424
const nextUrlRef = computed(() => unref(pageInfoRef).nextUrl)
25-
const imageListRef = useImageList()
25+
const rawImageListRef = useRawImageList()
2626
const imageInfoMapRef = useImageInfoMap()
2727
const loadingStatusRef = computed(() => {
28-
const total = unref(imageListRef).length
28+
const total = unref(rawImageListRef).length
2929
const loaded = unref(imageInfoMapRef).filter(info => info).length
3030
return {
3131
total,

‎src/monkey/copymanga-enhance/scripts/detail/newPage/component/Image/index.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { DirectionMode, PageType } from "../../constant";
22
import useDirectionMode from "../../hooks/useDirectionMode";
33
import useImageInfoMap from "../../hooks/useImageInfoMap";
4-
import useImageList from "../../hooks/useImageList";
4+
import useRawImageList from "../../hooks/useRawImageList";
55
import useImageWidth from "../../hooks/useImageWidth";
66
import { defineComponent, h, ref, unref } from "../../vue";
77

@@ -14,12 +14,12 @@ export default defineComponent({
1414
},
1515
setup (props, { emit }) {
1616
const pageType = ref(PageType.PORTRAIT)
17-
const imageListRef = useImageList()
17+
const rawImageListRef = useRawImageList()
1818
const imageInfoMapRef = useImageInfoMap()
1919
const [directionModeRef] = useDirectionMode()
2020
const [imageWidthRef] = useImageWidth()
2121
const onLoad = (e: Event) => {
22-
const index = unref(imageListRef).indexOf(props.src)
22+
const index = unref(rawImageListRef).indexOf(props.src)
2323
const element = e.target as HTMLImageElement
2424
const [width, height] = [element.naturalWidth, element.naturalHeight]
2525
const type = width > height ? PageType.LANDSCAPE : PageType.PORTRAIT

0 commit comments

Comments
 (0)