Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions packages/mobile/src/components/PostDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
<Toolbar @reply="isSticky = !isSticky;currentComment = null"></Toolbar>
</div>

<div ref="topicTipBox" class="native-topic-tip"></div>

<div class="my-box" v-if="topReply.length && config.showTopReply">
<div class="my-cell flex " @click="collapseTopReplyList">
<span class=" ">高赞回复</span>
Expand Down Expand Up @@ -305,10 +307,7 @@ export default {
return []
},
topReply() {
return this.post.replyList
.filter(v => v.thankCount >= this.config.topReplyLoveMinCount)
.sort((a, b) => b.thankCount - a.thankCount)
.slice(0, this.config.topReplyCount)
return this.post.topReplyList
},
replyList() {
// console.log('this.post.nestedReplies', this.post.nestedReplies)
Expand Down Expand Up @@ -358,6 +357,7 @@ export default {
}
},
'post.headerTemplate'(n, o) {
nextTick(this.mountTopicTipBox)
let mountEl = document.querySelector('.main-wrapper .post-wrapper .html-wrapper .header')
if (mountEl) {
this.showOpTag = true
Expand Down Expand Up @@ -394,6 +394,7 @@ export default {
},
mounted() {
this.debounceScroll = debounce(this.scroll, 300, false)
this.mountTopicTipBox()
if (this.isLogin) {
const observer = new IntersectionObserver(
([e]) => e.target.toggleAttribute('stuck', e.intersectionRatio < 1),
Expand Down Expand Up @@ -542,6 +543,16 @@ export default {
collapseTopReplyList() {
$(this.$refs.topReply).slideToggle('fast')
},
mountTopicTipBox() {
if (!this.isPost) return

const mountEl = this.$refs.topicTipBox
const tipBox = document.querySelector('#topic-tip-box')
if (!mountEl || !tipBox) return

mountEl.append(tipBox)
tipBox.style.display = ''
},
goBottom() {
this.isSticky = false
setTimeout(() => {
Expand Down Expand Up @@ -675,6 +686,16 @@ export default {
}
}

.native-topic-tip {
width: 100%;

:deep(#topic-tip-box) {
display: block;
width: 100%;
box-sizing: border-box;
}
}

.loading-wrapper {
height: 20rem;
display: flex;
Expand Down
93 changes: 60 additions & 33 deletions packages/mobile/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,54 @@
import {createApp} from 'vue';
import App from './pages/App.vue';
import {GM_notification} from "gmApi"
import './global.d.ts'
import {PageType, Post, Reply} from "@v2next/core/types"
import {DefaultUser, functions, getDefaultConfig, getDefaultPost} from "@v2next/core";

let isMobile = !document.querySelector('#Rightbar');

function isReplyCell(cell: Element) {
return /^r_\d+$/.test(cell.id)
}

function findReplyBoxMobile(boxs: any) {
// 根据内容的元素属性特征定位回复区域
let fallbackBox

// 根据回复 cell 的稳定 id 特征定位回复区域
for (let i = 1; i < boxs.length; i++) {
const box = boxs[i];
const cells = box.querySelectorAll ? box.querySelectorAll('.cell') : [];

if (cells && cells.length > 0) {

if (!cells || !cells.length || box.id === 'topic-tip-box' || box.id === 'reply-box') {
continue
}

if (Array.from(cells).some((cell: any) => isReplyCell(cell))) {
return box;
}

if (!fallbackBox) {
const firstCell = cells[0];
if (firstCell.querySelector?.('.snow')) {
return box;
}
if (firstCell.querySelector?.('.snow')) {
fallbackBox = box;
} else if (box.querySelector?.('.page_normal')) {
fallbackBox = box;
}
}
}

// 回退逻辑
console.warn('[V2Next] 无法智能检测回复区域,使用默认位置');
return boxs[1];
return fallbackBox;
}

function applyNestedReplyCounts(post: Post) {
const replyByFloor = new Map(post.replyList.map(reply => [Number(reply.floor), reply]))

post.nestedReplies.forEach((nestedReply) => {
const reply = replyByFloor.get(Number(nestedReply.floor))
if (reply) {
reply.replyCount = nestedReply.replyCount
}
})
}

let $section = document.createElement('section')
Expand Down Expand Up @@ -227,7 +252,7 @@ function run() {
box = findReplyBoxMobile(boxs)
}

let cells: any = box.querySelectorAll('.cell')
let cells: any = box?.querySelectorAll('.cell')

if (cells && cells.length) {
// post.fr = boxs[1].querySelector('.inner')!.innerHTML
Expand All @@ -239,19 +264,17 @@ function run() {

let repliesMap: any[] = []
//如果第二条有id,就说明是第二条是回复。只有一页回复
if (cells[1].id) {
if (cells[1] && isReplyCell(cells[1])) {
repliesMap.push({i: pageNo, replyList: this.parsePageReplies(cells.slice(1))})
let replyList = functions.getAllReply(repliesMap)
post.replyList = replyList
post.replyCount = replyList.length
post.allReplyUsers = Array.from(new Set(replyList.map((v: any) => v.username)))
post.nestedReplies = functions.createNestedList(replyList)
post.nestedRedundReplies = functions.createNestedRedundantList(replyList)
post.nestedReplies.map((v) => {
post.replyList[Number(v.floor) - 1].replyCount = v.replyCount
})
functions.createList(post, replyList)
applyNestedReplyCounts(post)
return post
} else {
if (!cells[1]) {
return post
}

let promiseList: any = []
// console.log(this.current.repliesMap)
return new Promise((resolve, reject) => {
Expand All @@ -270,20 +293,15 @@ function run() {

results.filter((result) => result.status === "fulfilled").map(v => repliesMap.push(v.value))
let replyList = functions.getAllReply(repliesMap)
post.replyList = replyList
post.replyCount = replyList.length
post.allReplyUsers = Array.from(new Set(replyList.map((v: any) => v.username)))
post.nestedReplies = functions.createNestedList(replyList)
post.nestedRedundReplies = functions.createNestedRedundantList(replyList)
post.nestedReplies.map((v) => {
post.replyList[Number(v.floor) - 1].replyCount = v.replyCount
})
functions.createList(post, replyList)
applyNestedReplyCounts(post)
resolve(post)
}
)
})
}
}
return post
},
//请求帖子其他页的回复
fetchPostOtherPageReplies(href: string, pageNo: number) {
Expand All @@ -298,7 +316,11 @@ function run() {
box = findReplyBoxMobile(boxs)
}
})
let cells: any = box!.querySelectorAll('.cell')
let cells: any = box?.querySelectorAll('.cell')
if (!cells || !cells.length) {
resolve({i: pageNo, replyList: []})
return
}
cells = Array.from(cells)
resolve({i: pageNo, replyList: this.parsePageReplies(cells.slice(2, cells.length - 1))})
}).catch((r: any) => {
Expand Down Expand Up @@ -1007,7 +1029,12 @@ if (isMobile) {
})();

run()
let vueApp = createApp(App)
vueApp.config.unwrapInjectedRef = true
vueApp.mount($section);
}
Promise.all([
import('vue'),
import('./pages/App.vue'),
]).then(([{createApp}, {default: App}]) => {
let vueApp = createApp(App)
vueApp.config.unwrapInjectedRef = true
vueApp.mount($section);
})
}
12 changes: 2 additions & 10 deletions packages/mobile/src/pages/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,10 @@ export default {
regenerateReplyList() {
// console.log('重新生成列表')
if (this.current.replyList.length) {
this.current.replyCount = this.current.replyList.length
let res = functions.createNestedList(this.current.replyList)
if (res) {
this.current.nestedReplies = res
}
let dup_res = functions.createNestedRedundantList(this.current.replyList)
if (dup_res) {
this.current.nestedRedundReplies = dup_res
}
functions.createList(this.current, this.current.replyList)
} else {
this.current.replyCount = 0
this.current.topReplyList = []
this.current.nestedReplies = []
this.current.nestedRedundReplies = []
}
Expand Down Expand Up @@ -679,4 +672,3 @@ export default {
gap: 1rem;
}
</style>

12 changes: 12 additions & 0 deletions packages/mobile/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ export default defineConfig({
},
build: {
fileName:'V2Next-Mobile.user.js',
cssSideEffects: (css: string) => `
(() => {
if (document.querySelector('#Rightbar')) return;
if (typeof GM_addStyle === 'function') {
GM_addStyle(${JSON.stringify(css)});
return;
}
const style = document.createElement('style');
style.textContent = ${JSON.stringify(css)};
document.head.append(style);
})();
`,
externalGlobals: {
vue: cdn.jsdelivr('Vue', 'dist/vue.global.prod.js'),
},
Expand Down
5 changes: 4 additions & 1 deletion packages/pc/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,10 @@ export default {
showPost() {
this.show = true
$(`#Wrapper #Main .box:lt(3)`).each(function () {
if (this.id === 'topic-tip-box' || this.querySelector('#topic-tip-box')) {
$(this).show()
return
}
$(this).hide()
})
},
Expand Down Expand Up @@ -1066,4 +1070,3 @@ export default {
}
}
</style>

23 changes: 23 additions & 0 deletions packages/pc/src/components/PostDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
:api-url="'topic/'+post.id"/>
</Toolbar>
</div>
<div ref="topicTipMount" class="topic-tip-mount"></div>

<div class="my-box" v-if="post.topReplyList.length && config.showTopReply">
<div class="my-cell flex " @click.stop="collapseTopReplyList">
Expand Down Expand Up @@ -512,6 +513,7 @@ export default {
this.$refs?.detail?.scrollTo({top: 0})
})
}
this.moveTopicTipBox()
},
'post.headerTemplate'(n, o) {
let mountEl = document.querySelector('.main-wrapper .post-wrapper .html-wrapper .header')
Expand All @@ -527,6 +529,7 @@ export default {
this.currentFloor = ''
nextTick(() => {
this.$refs?.main?.focus()
this.moveTopicTipBox()
})
} else {
this.isSticky = false
Expand All @@ -537,6 +540,7 @@ export default {
},
mounted() {
nextTick(() => {
this.moveTopicTipBox()
setTimeout(() => {
this.postDetailWidth = this.$refs.mainWrapper?.getBoundingClientRect().width || 0
}, 500)
Expand Down Expand Up @@ -582,6 +586,14 @@ export default {
eventBus.off(CMD.SHOW_CALL)
},
methods: {
moveTopicTipBox() {
nextTick(() => {
let topicTipBox = document.querySelector('#topic-tip-box')
if (!topicTipBox || !this.$refs.topicTipMount) return
this.$refs.topicTipMount.appendChild(topicTipBox)
topicTipBox.style.display = ''
})
},
addTag() {
eventBus.emit(CMD.ADD_TAG, this.post.member.username)
},
Expand Down Expand Up @@ -979,6 +991,17 @@ export default {
}
}

.topic-tip-mount {
width: 100%;
margin-bottom: 2rem;

:deep(#topic-tip-box) {
width: 100%;
margin: 0;
box-sizing: border-box;
}
}

.loading-wrapper {
height: 20rem;
display: flex;
Expand Down
Loading