mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2025-05-19 10:00:13 +09:00
新增:文章详情页面添加弹幕功能;
修改:修复友链列表单分组显示问题; 优化;对恋爱日记清单列表进行优化
This commit is contained in:
parent
f12262f4df
commit
9573b303e2
@ -65,14 +65,14 @@ export default {
|
|||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 1.2em;
|
font-size: 1.12em;
|
||||||
`,
|
`,
|
||||||
h5: `
|
h5: `
|
||||||
color: var(--main);
|
color: var(--main);
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 16px;
|
font-size: 1.1em;
|
||||||
`,
|
`,
|
||||||
h6: `
|
h6: `
|
||||||
color: #303133;
|
color: #303133;
|
||||||
@ -90,7 +90,7 @@ export default {
|
|||||||
strong: 'font-weight: 700;color: rgb(248, 57, 41);',
|
strong: 'font-weight: 700;color: rgb(248, 57, 41);',
|
||||||
video: 'width: 100%',
|
video: 'width: 100%',
|
||||||
},
|
},
|
||||||
containStyle: 'font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;padding:12px;font-size: 16px;color: #606266;word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 6px;background-color:#FFFFFF;',
|
containStyle: 'font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;padding:12px;font-size: 14px;color: #606266;word-spacing: 0.8px;letter-spacing: 0.8px;border-radius: 6px;background-color:#FFFFFF;',
|
||||||
|
|
||||||
loadingGif: HaloConfig.loadingGifUrl,
|
loadingGif: HaloConfig.loadingGifUrl,
|
||||||
emptyGif: HaloConfig.loadingEmptyUrl,
|
emptyGif: HaloConfig.loadingEmptyUrl,
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<view style="overflow: hidden;position: fixed;width: 100%;height: 100%;pointer-events: none; top: 0;">
|
<view class="barrage-wrap" :class="[type]">
|
||||||
<view class="danmu-li" v-for="(item, index) in listData" :class="item.type" :style="item.style" :key="index">
|
<view class="danmu-li" v-for="(item, index) in listData" :class="[type, item.type]" :style="[item.style]" :key="index">
|
||||||
<view class="danmu-inner">
|
<view class="danmu-inner">
|
||||||
<view class="user-box">
|
<view class="user-box">
|
||||||
<view class="user-img">
|
<view class="user-img"><image class="avatar" :src="item.item.avatar"></image></view>
|
||||||
<view class="img-box">
|
<view class="user-text cl1">{{ item.item.author }}</view>
|
||||||
<image :src="item.avatar || 'https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=317894666,3379114684&fm=26&gp=0.jpg'"></image>
|
<view class="user-status cl1">{{ item.item.content }}</view>
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="user-text cl1">{{ item.nickName }}</view>
|
|
||||||
<view class="user-status cl1">{{ item.text }}</view>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -23,6 +19,12 @@ export default {
|
|||||||
type: String,
|
type: String,
|
||||||
default: 'rightToLeft'
|
default: 'rightToLeft'
|
||||||
},
|
},
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
minTime: {
|
minTime: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 4
|
default: 4
|
||||||
@ -43,34 +45,35 @@ export default {
|
|||||||
//轨道高度
|
//轨道高度
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 40
|
default: 40
|
||||||
},
|
|
||||||
noStacked: {
|
|
||||||
//不允许堆叠(暂不可用)
|
|
||||||
type: Array,
|
|
||||||
default() {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
closeTimer: null,
|
||||||
listData: []
|
listData: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.hrackNum = Math.floor((this.maxTop - this.minTop) / this.hrackH);
|
//leftBottom 使用参数
|
||||||
|
if (this.type === 'leftBottom') {
|
||||||
|
this.hrackNum = Math.floor(this.maxTop / this.hrackH);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
add(obj) {
|
add(obj) {
|
||||||
|
console.log('加载弹幕中...');
|
||||||
|
this.isShow = true;
|
||||||
|
this.showFlag = true;
|
||||||
let data = {
|
let data = {
|
||||||
item: obj.item,
|
...obj,
|
||||||
id: Date.parse(new Date()),
|
id: Date.parse(new Date()),
|
||||||
time: Math.ceil(Math.floor(Math.random() * (this.maxTime - this.minTime + 1) + this.minTime)),
|
time: Math.ceil(Math.floor(Math.random() * (this.maxTime - this.minTime + 1) + this.minTime)),
|
||||||
type: this.type
|
type: this.type
|
||||||
};
|
};
|
||||||
if (this.type === 'leftBottom') {
|
if (this.type === 'leftBottom') {
|
||||||
|
console.log('leftBottom,加载弹幕中...');
|
||||||
let objData = {
|
let objData = {
|
||||||
item: data.item,
|
item: data,
|
||||||
type: 'leftBottomEnter',
|
type: 'leftBottomEnter',
|
||||||
style: {
|
style: {
|
||||||
transition: `all 0.5s`,
|
transition: `all 0.5s`,
|
||||||
@ -88,7 +91,7 @@ export default {
|
|||||||
} else if (this.listData[i].status === 'reset') {
|
} else if (this.listData[i].status === 'reset') {
|
||||||
//重置
|
//重置
|
||||||
this.listData[i].style.transition = 'none';
|
this.listData[i].style.transition = 'none';
|
||||||
this.listData[i].style.bottom = 0;
|
this.listData[i].style.bottom = '6px';
|
||||||
this.listData[i].status = 'reuse';
|
this.listData[i].status = 'reuse';
|
||||||
} else if (this.listData[i].status === 'recycle') {
|
} else if (this.listData[i].status === 'recycle') {
|
||||||
//回收
|
//回收
|
||||||
@ -105,8 +108,16 @@ export default {
|
|||||||
if (listLen < hrackNum + 2) {
|
if (listLen < hrackNum + 2) {
|
||||||
this.listData.push(objData);
|
this.listData.push(objData);
|
||||||
}
|
}
|
||||||
} else if (this.type === 'rightToLeft' || this.type === 'leftToRight') {
|
} else if (this.type === 'rightToLeft') {
|
||||||
let objData = this.horStacked(data);
|
let objData = {
|
||||||
|
item: data.item,
|
||||||
|
type: 'rightToLeft',
|
||||||
|
style: {
|
||||||
|
animationDuration: `${data.time}s`,
|
||||||
|
top: `${Math.ceil(Math.random() * (this.maxTop - this.minTop + 1) + this.minTop)}px`
|
||||||
|
},
|
||||||
|
delTime: Date.parse(new Date()) + data.time * 1200
|
||||||
|
};
|
||||||
for (let i in this.listData) {
|
for (let i in this.listData) {
|
||||||
if (this.listData[i].delTime <= Date.parse(new Date())) {
|
if (this.listData[i].delTime <= Date.parse(new Date())) {
|
||||||
this.repaint(i, objData.type);
|
this.repaint(i, objData.type);
|
||||||
@ -118,16 +129,40 @@ export default {
|
|||||||
this.listData.push(objData);
|
this.listData.push(objData);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
horStacked(data) {
|
async remove(options = {}) {
|
||||||
return {
|
options = Object.assign(
|
||||||
item: data.item,
|
{},
|
||||||
type: this.type,
|
{
|
||||||
style: {
|
duration: 5000, // 延迟关闭的时间
|
||||||
animationDuration: `${data.time}s`,
|
speed: 1000 // 弹幕消失的速度
|
||||||
top: `${Math.ceil(Math.random() * (this.maxTop - this.minTop + 1) + this.minTop)}px`
|
|
||||||
},
|
},
|
||||||
delTime: Date.parse(new Date()) + data.time * 1200
|
options
|
||||||
|
);
|
||||||
|
|
||||||
|
const _fnHandleRemove = item => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
item['type'] = 'leftBottomExitLeft';
|
||||||
|
// this.$forceUpdate();
|
||||||
|
resolve();
|
||||||
|
}, options.speed);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
const _fnHandleLoop = item => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
for (var i = 0; i < this.listData.length; i++) {
|
||||||
|
await _fnHandleRemove(this.listData[i]);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
}, options.duration);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
await _fnHandleLoop();
|
||||||
|
setTimeout(() => {
|
||||||
|
this.listData = [];
|
||||||
|
}, 100);
|
||||||
},
|
},
|
||||||
repaint(index, type) {
|
repaint(index, type) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -137,8 +172,8 @@ export default {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<style></style>
|
|
||||||
<style lang="scss">
|
<style lang="scss" scoped>
|
||||||
@keyframes leftBottomEnter {
|
@keyframes leftBottomEnter {
|
||||||
0% {
|
0% {
|
||||||
transform: translateY(100%);
|
transform: translateY(100%);
|
||||||
@ -163,6 +198,17 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes leftBottomExitLeft {
|
||||||
|
0% {
|
||||||
|
transform: translateX(0%);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(-200%);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@keyframes leftToRight {
|
@keyframes leftToRight {
|
||||||
0% {
|
0% {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
@ -182,13 +228,32 @@ export default {
|
|||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.barrage-wrap {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
top: 0;
|
||||||
|
z-index: 99;
|
||||||
|
transition: all 1s ease-in-out;
|
||||||
|
&.leftBottom {
|
||||||
|
top: initial;
|
||||||
|
bottom: 130rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
.danmu-li {
|
.danmu-li {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
animation-timing-function: linear;
|
animation-timing-function: linear;
|
||||||
|
transition: transform 0.5s ease-in-out;
|
||||||
|
|
||||||
|
&.is-hide {
|
||||||
|
transform: translateX(-100%) !important;
|
||||||
|
}
|
||||||
|
&.leftBottom {
|
||||||
|
left: 24rpx;
|
||||||
|
}
|
||||||
&.leftBottomEnter {
|
&.leftBottomEnter {
|
||||||
animation-name: leftBottomEnter;
|
animation-name: leftBottomEnter;
|
||||||
}
|
}
|
||||||
@ -196,53 +261,59 @@ export default {
|
|||||||
animation-name: leftBottomExit;
|
animation-name: leftBottomExit;
|
||||||
animation-fill-mode: forwards;
|
animation-fill-mode: forwards;
|
||||||
}
|
}
|
||||||
|
&.leftBottomExitLeft {
|
||||||
|
animation-name: leftBottomExitLeft;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
&.rightToLeft {
|
&.rightToLeft {
|
||||||
animation-name: rightToLeft;
|
animation-name: rightToLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.leftToRight {
|
&.leftToRight {
|
||||||
animation-name: leftToRight;
|
animation-name: rightToLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
.danmu-inner {
|
.danmu-inner {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
font-size: 24rpx;
|
||||||
.user-box {
|
.user-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 3rpx 40rpx 3rpx 10rpx;
|
padding: 6rpx 40rpx 6rpx 10rpx;
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 32rpx;
|
border-radius: 32rpx;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
.user-img {
|
.user-img {
|
||||||
.img-box {
|
display: flex;
|
||||||
display: flex;
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
image {
|
.avatar {
|
||||||
width: 58rpx;
|
width: 42rpx;
|
||||||
height: 58rpx;
|
height: 42rpx;
|
||||||
background: rgba(55, 55, 55, 1);
|
background: rgba(55, 55, 55, 1);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-status {
|
.user-status {
|
||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
|
max-width: 320rpx;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-text {
|
.user-text {
|
||||||
|
max-width: 100rpx;
|
||||||
margin-left: 10rpx;
|
margin-left: 10rpx;
|
||||||
// white-space: nowrap;
|
|
||||||
font-size: 28rpx;
|
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
width: 80rpx;
|
|
||||||
color: rgba(255, 255, 255, 1);
|
color: rgba(255, 255, 255, 1);
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -143,6 +143,7 @@ export default {
|
|||||||
this.result = res.data;
|
this.result = res.data;
|
||||||
this.dataList = res.data.content;
|
this.dataList = res.data.content;
|
||||||
this.loading = 'success';
|
this.loading = 'success';
|
||||||
|
this.$emit('on-loaded', this.dataList);
|
||||||
} else {
|
} else {
|
||||||
this.loading = 'error';
|
this.loading = 'error';
|
||||||
}
|
}
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
#如何使用
|
|
||||||
###js
|
|
||||||
```javascript
|
|
||||||
import lffBarrage from '@/components/lff-barrage/lff-barrage.vue'
|
|
||||||
components:{lffBarrage},
|
|
||||||
methods:{
|
|
||||||
colrdo(){ //插入一条弹幕
|
|
||||||
this.$refs.lffBarrage.add({item:'你好呀小伙子'});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
###HTML
|
|
||||||
```html
|
|
||||||
<lff-barrage ref="lffBarrage"></lff-barrage>
|
|
||||||
```
|
|
@ -20,12 +20,11 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return { _scrollTop: 0 };
|
return { timer: null, _scrollTop: 0 };
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
scrollTop(val) {
|
scrollTop(val) {
|
||||||
this._scrollTop = val;
|
this._scrollTop = val;
|
||||||
console.log('监听1:', val);
|
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -35,11 +34,18 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
fnScroll() {
|
fnScroll() {
|
||||||
throttle(() => {
|
throttle(() => {
|
||||||
|
this.$emit('on-status', false);
|
||||||
const isTop = this._scrollTop >= 180;
|
const isTop = this._scrollTop >= 180;
|
||||||
this._scrollTop = isTop ? 0 : 999999;
|
this._scrollTop = isTop ? 0 : 999999999999;
|
||||||
uni.pageScrollTo({
|
uni.pageScrollTo({
|
||||||
duration: 500,
|
duration: 500,
|
||||||
scrollTop: this._scrollTop
|
scrollTop: this._scrollTop,
|
||||||
|
success: () => {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
this.timer = setTimeout(() => {
|
||||||
|
this.$emit('on-status', true);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.$emit('update:scrollTop', this._scrollTop);
|
this.$emit('update:scrollTop', this._scrollTop);
|
||||||
});
|
});
|
||||||
|
@ -15,10 +15,10 @@ export default {
|
|||||||
girl: {
|
girl: {
|
||||||
name: '未知女主',
|
name: '未知女主',
|
||||||
avatar: 'https://b.925i.cn/uni_halo_love/love_girl.png',
|
avatar: 'https://b.925i.cn/uni_halo_love/love_girl.png',
|
||||||
birthday: '2022-07-25', // 生日
|
birthday: '2022-04-19', // 生日
|
||||||
},
|
},
|
||||||
timeTitle: '这是我们一起走过的',
|
timeTitle: '这是我们一起走过的',
|
||||||
loveStartDate: '2022-05-20 13:14:20', // 恋爱开始时间
|
loveStartDate: '2022-04-10 13:14:20', // 恋爱开始时间
|
||||||
|
|
||||||
nav: [{
|
nav: [{
|
||||||
key: 'journey',
|
key: 'journey',
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<view class="app-page pb-24">
|
<view class="app-page pb-24">
|
||||||
<!-- 博主信息 -->
|
<!-- 博主信息 -->
|
||||||
<view class="blogger-info" :style="[calcProfileStyle]">
|
<view class="blogger-info" :style="[calcProfileStyle]">
|
||||||
<image class="avatar" :src="$utils.checkAvatarUrl(bloggerInfo.avatar)" mode="aspectFill" @click="miniProfileCard.show = true"></image>
|
<image class="avatar" :src="$utils.checkAvatarUrl(bloggerInfo.avatar)" mode="aspectFill"></image>
|
||||||
<view class="profile">
|
<view class="profile">
|
||||||
<view class="author mt-24 text-size-g text-weight-b">{{ bloggerInfo.nickname }}</view>
|
<view class="author mt-24 text-size-g text-weight-b">{{ bloggerInfo.nickname }}</view>
|
||||||
<view class="desc mt-24 text-size-m">{{ bloggerInfo.description || '这个博主很懒,竟然没写介绍~' }}</view>
|
<view class="desc mt-24 text-size-m">{{ bloggerInfo.description || '这个博主很懒,竟然没写介绍~' }}</view>
|
||||||
|
@ -13,16 +13,34 @@
|
|||||||
|
|
||||||
<!-- 如果只有一个分组:使用列表的形式 result.length == 1 -->
|
<!-- 如果只有一个分组:使用列表的形式 result.length == 1 -->
|
||||||
<view v-else-if="result.length == 1" class="flex flex-col pb-24">
|
<view v-else-if="result.length == 1" class="flex flex-col pb-24">
|
||||||
<block v-for="(item, index) in result[0].children" :key="index">
|
<block v-for="(link, index) in result[0].children" :key="index">
|
||||||
<tm-translate animation-name="fadeUp" :wait="(index + 1) * 50">
|
<tm-translate animation-name="fadeUp" :wait="(index + 1) * 50">
|
||||||
<view class="link-card one round-a-6 flex ma-24 mb-0 pa-24" @click="fnOnLinkEvent(item)">
|
<!-- 色彩版本 -->
|
||||||
<cache-image class="logo shadow-2" radius="12rpx" width="80rpx" height="80rpx" :url="item.logo" :fileMd5="item.logo" mode="aspectFill"></cache-image>
|
<view
|
||||||
|
v-if="!globalAppSettings.links.useSimple"
|
||||||
|
class="info flex pt-24 pb-24 pl-12 pr-12 border-b-1"
|
||||||
|
:class="{ 'border-b-1': index != team.children.length - 1 }"
|
||||||
|
@click="fnOnLinkEvent(link)"
|
||||||
|
>
|
||||||
|
<view class="link-logo"><cache-image class="link-logo_img" radius="12rpx" :url="link.logo" :fileMd5="link.logo" mode="aspectFill"></cache-image></view>
|
||||||
|
<view class="flex flex-col pl-30 info-detail">
|
||||||
|
<view class="link-card_name text-size-l text-weight-b text-red">{{ link.name }}</view>
|
||||||
|
<view class="poup-tag ml--10 mt-6">
|
||||||
|
<tm-tags color="bg-gradient-amber-accent" :shadow="0" size="s" model="fill">ID:{{ link.id }}</tm-tags>
|
||||||
|
<tm-tags color=" bg-gradient-light-blue-lighten" :shadow="0" size="s" model="fill">{{ link.team || '暂未分组' }}</tm-tags>
|
||||||
|
</view>
|
||||||
|
<view class="link-card_desc text-overflow text-size-s mt-4">博客简介:{{ link.description || '这个博主很懒,没写简介~' }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 简洁版本 -->
|
||||||
|
<view v-else class="link-card flex ml-24 mr-24 pt-24 pb-24" @click="fnOnLinkEvent(link)">
|
||||||
|
<image class="logo shadow-6" :src="link.logo" mode="aspectFill"></image>
|
||||||
<view class="info pl-24">
|
<view class="info pl-24">
|
||||||
<view class="name text-size-g">{{ item.name }}</view>
|
<view class="name text-size-g">{{ link.name }}</view>
|
||||||
<view class="desc mt-12 text-size-s text-grey-darken-1">{{ item.description }}</view>
|
<view class="desc mt-12 text-size-s text-grey-darken-1">{{ link.description }}</view>
|
||||||
<view class="link mt-12 text-size-m text-grey-darken-1">
|
<view v-if="false" class="link mt-12 text-size-m text-grey-darken-1">
|
||||||
<text class="iconfont icon-link mr-6 text-size-s"></text>
|
<text class="iconfont icon-link mr-6 text-size-s"></text>
|
||||||
{{ item.url }}
|
{{ link.url }}
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@ -51,7 +69,7 @@
|
|||||||
<view class="link-card_name text-size-l text-weight-b text-red">{{ link.name }}</view>
|
<view class="link-card_name text-size-l text-weight-b text-red">{{ link.name }}</view>
|
||||||
<view class="poup-tag ml--10 mt-6">
|
<view class="poup-tag ml--10 mt-6">
|
||||||
<tm-tags color="bg-gradient-amber-accent" :shadow="0" size="s" model="fill">ID:{{ link.id }}</tm-tags>
|
<tm-tags color="bg-gradient-amber-accent" :shadow="0" size="s" model="fill">ID:{{ link.id }}</tm-tags>
|
||||||
<tm-tags color=" bg-gradient-light-blue-lighten" :shadow="0" size="s" model="fill">{{ link.team }}</tm-tags>
|
<tm-tags color=" bg-gradient-light-blue-lighten" :shadow="0" size="s" model="fill">{{ link.team || '暂未分组' }}</tm-tags>
|
||||||
</view>
|
</view>
|
||||||
<view class="link-card_desc text-overflow text-size-s mt-4">博客简介:{{ link.description || '这个博主很懒,没写简介~' }}</view>
|
<view class="link-card_desc text-overflow text-size-s mt-4">博客简介:{{ link.description || '这个博主很懒,没写简介~' }}</view>
|
||||||
</view>
|
</view>
|
||||||
@ -86,7 +104,7 @@
|
|||||||
<view class="poup-name text-size-lg text-weight-b">{{ detail.data.name }}</view>
|
<view class="poup-name text-size-lg text-weight-b">{{ detail.data.name }}</view>
|
||||||
<view class="poup-tag ml--10">
|
<view class="poup-tag ml--10">
|
||||||
<tm-tags color="bg-gradient-amber-accent" size="n" model="fill">ID:{{ detail.data.id }}</tm-tags>
|
<tm-tags color="bg-gradient-amber-accent" size="n" model="fill">ID:{{ detail.data.id }}</tm-tags>
|
||||||
<tm-tags color="bg-gradient-light-blue-lighten" size="n" model="fill">{{ detail.data.team }}</tm-tags>
|
<tm-tags color="bg-gradient-light-blue-lighten" size="n" model="fill">{{ detail.data.team || '暂未分组' }}</tm-tags>
|
||||||
</view>
|
</view>
|
||||||
<view class="poup-link text-size-m" @click="fnCopyLink(detail.data)">
|
<view class="poup-link text-size-m" @click="fnCopyLink(detail.data)">
|
||||||
<text class="text-orange">{{ detail.data.url }}</text>
|
<text class="text-orange">{{ detail.data.url }}</text>
|
||||||
|
@ -105,10 +105,18 @@
|
|||||||
|
|
||||||
<!-- 评论展示区域 -->
|
<!-- 评论展示区域 -->
|
||||||
<view class="comment-wrap bg-white mt-24 pa-24 round-4">
|
<view class="comment-wrap bg-white mt-24 pa-24 round-4">
|
||||||
<commentList :disallowComment="result.disallowComment" :postId="result.id" :post="result" @on-comment-detail="fnOnShowCommentDetail"></commentList>
|
<commentList
|
||||||
|
:disallowComment="result.disallowComment"
|
||||||
|
:postId="result.id"
|
||||||
|
:post="result"
|
||||||
|
@on-comment-detail="fnOnShowCommentDetail"
|
||||||
|
@on-loaded="fnOnCommentLoaded"
|
||||||
|
></commentList>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<!-- 弹幕效果 -->
|
||||||
|
<barrage ref="barrage" :maxTop="240" type="leftBottom"></barrage>
|
||||||
<!-- 返回顶部 -->
|
<!-- 返回顶部 -->
|
||||||
<tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent" @click="fnToTopPage()"></tm-flotbutton>
|
<tm-flotbutton :offset="[16, 80]" icon="icon-angle-up" color="bg-gradient-light-blue-accent" @click="fnToTopPage()"></tm-flotbutton>
|
||||||
<tm-flotbutton :actions="btnOption.actions" actions-pos="left" :show-text="true" color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton>
|
<tm-flotbutton :actions="btnOption.actions" actions-pos="left" :show-text="true" color="bg-gradient-orange-accent" @change="fnOnFlotButtonChange"></tm-flotbutton>
|
||||||
@ -190,6 +198,7 @@ import commentList from '@/components/comment-list/comment-list.vue';
|
|||||||
import commentItem from '@/components/comment-item/comment-item.vue';
|
import commentItem from '@/components/comment-item/comment-item.vue';
|
||||||
|
|
||||||
import rCanvas from '@/components/r-canvas/r-canvas.vue';
|
import rCanvas from '@/components/r-canvas/r-canvas.vue';
|
||||||
|
import barrage from '@/components/barrage/barrage.vue';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
tmSkeleton,
|
tmSkeleton,
|
||||||
@ -200,7 +209,8 @@ export default {
|
|||||||
mpHtml,
|
mpHtml,
|
||||||
commentList,
|
commentList,
|
||||||
commentItem,
|
commentItem,
|
||||||
rCanvas
|
rCanvas,
|
||||||
|
barrage
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
@ -629,6 +639,48 @@ export default {
|
|||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: `/pagesA/tag-detail/tag-detail?id=${tag.id}&slug=${tag.slug}&name=${tag.name}`
|
url: `/pagesA/tag-detail/tag-detail?id=${tag.id}&slug=${tag.slug}&name=${tag.name}`
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
async fnOnCommentLoaded(data) {
|
||||||
|
const _list = [];
|
||||||
|
const _handleData = list => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
if (list.length == 0) {
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
list.forEach(item => {
|
||||||
|
_list.push(item);
|
||||||
|
if (item.children && item.children.length != 0) {
|
||||||
|
_handleData(item.children);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
await _handleData(data);
|
||||||
|
if (this.globalAppSettings.barrage.use) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
_handleAddBarrage();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const _handleRemove = () => {
|
||||||
|
this.$refs['barrage'].remove({
|
||||||
|
duration: 5000, // 延迟关闭的时间
|
||||||
|
speed: 1000 // 弹幕消失的速度
|
||||||
|
});
|
||||||
|
};
|
||||||
|
let index = 0;
|
||||||
|
const _handleAddBarrage = () => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$refs['barrage'].add(_list[index]);
|
||||||
|
index += 1;
|
||||||
|
if (index < _list.length - 1) {
|
||||||
|
_handleAddBarrage();
|
||||||
|
} else {
|
||||||
|
_handleRemove();
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -303,7 +303,8 @@ export default {
|
|||||||
&-desc {
|
&-desc {
|
||||||
margin-top: 24rpx;
|
margin-top: 24rpx;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
font-size: 28rpx;
|
font-size: 30rpx;
|
||||||
|
color: rgba(26, 26, 26, 0.9);
|
||||||
&.is-empty {
|
&.is-empty {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="app-page">
|
<view class="app-page" @touchstart="fnOnTouchstart" @touchend="fnOnTouchend" @touchcancel="fnOnTouchend">
|
||||||
<view class="love-card">
|
<view class="love-card" :class="{ ani: isDoAni }">
|
||||||
<view class="head">
|
<view class="head">
|
||||||
<image class="avatar" :src="loveConfig.boy.avatar" mode="scaleToFill"></image>
|
<image class="avatar" :src="loveConfig.boy.avatar" mode="scaleToFill"></image>
|
||||||
<view class="love-days">
|
<view class="love-days">
|
||||||
@ -31,7 +31,7 @@
|
|||||||
</view>
|
</view>
|
||||||
<view v-else class="list">
|
<view v-else class="list">
|
||||||
<block v-for="(item, index) in list" :key="index">
|
<block v-for="(item, index) in list" :key="index">
|
||||||
<view class="card" :style="{ '--delay': calcCardDelay(index) }">
|
<view class="card" :class="{ ani: isDoAni }" :style="{ '--delay': calcCardDelay(index) }">
|
||||||
<view class="head">
|
<view class="head">
|
||||||
<view class="status">
|
<view class="status">
|
||||||
<view v-if="!item.finish" class="text">进行中</view>
|
<view v-if="!item.finish" class="text">进行中</view>
|
||||||
@ -70,7 +70,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</block>
|
</block>
|
||||||
</view>
|
</view>
|
||||||
<scroll-btn :scrollTop.sync="scrollTop"></scroll-btn>
|
<scroll-btn :scrollTop.sync="scrollTop" @on-status="fnOnScrollStatus"></scroll-btn>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -81,6 +81,7 @@ export default {
|
|||||||
components: { ScrollBtn },
|
components: { ScrollBtn },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
isDoAni: true,
|
||||||
scrollTop: 0,
|
scrollTop: 0,
|
||||||
loveConfig: LoveConfig,
|
loveConfig: LoveConfig,
|
||||||
list: []
|
list: []
|
||||||
@ -142,6 +143,15 @@ export default {
|
|||||||
fnOnItemOpen(item) {
|
fnOnItemOpen(item) {
|
||||||
item.open = !item.open;
|
item.open = !item.open;
|
||||||
this.$forceUpdate();
|
this.$forceUpdate();
|
||||||
|
},
|
||||||
|
fnOnScrollStatus(isEnd) {
|
||||||
|
this.isDoAni = isEnd;
|
||||||
|
},
|
||||||
|
fnOnTouchstart() {
|
||||||
|
this.isDoAni = false;
|
||||||
|
},
|
||||||
|
fnOnTouchend() {
|
||||||
|
this.isDoAni = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -188,7 +198,9 @@ export default {
|
|||||||
background-color: rgba(255, 199, 184, 0.9);
|
background-color: rgba(255, 199, 184, 0.9);
|
||||||
margin-bottom: 52rpx;
|
margin-bottom: 52rpx;
|
||||||
box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.1);
|
box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.1);
|
||||||
animation: loveCardAni 3s ease-in-out infinite;
|
&.ani {
|
||||||
|
animation: loveCardAni 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.head {
|
.head {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -302,8 +314,10 @@ export default {
|
|||||||
background-color: #ffffff;
|
background-color: #ffffff;
|
||||||
margin-bottom: 36rpx;
|
margin-bottom: 36rpx;
|
||||||
box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.05);
|
box-shadow: 0rpx 4rpx 24rpx rgba(0, 0, 0, 0.05);
|
||||||
animation: cardAni 3s ease-in-out infinite;
|
|
||||||
animation-delay: var(--delay);
|
animation-delay: var(--delay);
|
||||||
|
&.ani {
|
||||||
|
animation: cardAni 3s ease-in-out infinite;
|
||||||
|
}
|
||||||
.head {
|
.head {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -78,6 +78,10 @@
|
|||||||
<text class="text-size-m ">友链简洁模式</text>
|
<text class="text-size-m ">友链简洁模式</text>
|
||||||
<tm-switch v-model="appSettings.links.useSimple" color="light-blue" :text="['是', '否']"></tm-switch>
|
<tm-switch v-model="appSettings.links.useSimple" color="light-blue" :text="['是', '否']"></tm-switch>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
|
||||||
|
<text class="text-size-m">启用评论弹幕</text>
|
||||||
|
<tm-switch v-model="appSettings.barrage.use" color="light-blue" :text="['是', '否']"></tm-switch>
|
||||||
|
</view>
|
||||||
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
|
<view class="mx-32 my-24 border-b-1 pb-24 flex-between">
|
||||||
<text class="text-size-m">是否圆形头像</text>
|
<text class="text-size-m">是否圆形头像</text>
|
||||||
<tm-switch v-model="appSettings.isAvatarRadius" color="light-blue" :text="['是', '否']"></tm-switch>
|
<tm-switch v-model="appSettings.isAvatarRadius" color="light-blue" :text="['是', '否']"></tm-switch>
|
||||||
|
@ -35,6 +35,11 @@ export const _DefaultAppSettings = {
|
|||||||
timeout: 3, // 屏蔽广告时长,时间到后自动恢复展示(单位小时)
|
timeout: 3, // 屏蔽广告时长,时间到后自动恢复展示(单位小时)
|
||||||
disabled: false, // 是否屏蔽广告(看广告可以关闭应用内设置的广告)
|
disabled: false, // 是否屏蔽广告(看广告可以关闭应用内设置的广告)
|
||||||
},
|
},
|
||||||
|
// 评论弹幕(文章详情)
|
||||||
|
barrage: {
|
||||||
|
use: true, // 是否启用
|
||||||
|
type: 'leftBottom' // 弹幕类型
|
||||||
|
},
|
||||||
gallery: {
|
gallery: {
|
||||||
// 是否使用瀑布流
|
// 是否使用瀑布流
|
||||||
useWaterfull: true
|
useWaterfull: true
|
||||||
|
Loading…
Reference in New Issue
Block a user