Skip to content

Commit

Permalink
feat: add sync status component
Browse files Browse the repository at this point in the history
  • Loading branch information
backrunner committed Aug 31, 2022
1 parent 2589473 commit 2ad31fc
Show file tree
Hide file tree
Showing 7 changed files with 223 additions and 2 deletions.
57 changes: 57 additions & 0 deletions src/components/common/SyncStatus.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<template>
<span
:class="{
'sync-status': true,
'sync-status--syncing': status === 'syncing',
'sync-status--completed': status && status !== 'syncing',
'sync-status--error': status === 'error',
}"
@click="handleClicked"
>
<Sync class="sync-status__icon sync-status__icon-sync" v-if="status === 'syncing'" />
<SyncError class="sync-status__icon sync-status__icon-error" v-if="status === 'error'" />
<CloudDone class="sync-status__icon sync-status__icon-done" v-if="status === 'done'" />
<div class="sync-status__text">{{ syncStatusText }}</div>
</span>
</template>

<script>
import Sync from '../icons/sync.vue';
import SyncError from '../icons/syncError.vue';
import CloudDone from '../icons/cloudDone.vue';
export default {
props: {
status: {
type: String,
},
},
components: {
Sync,
SyncError,
CloudDone,
},
computed: {
syncStatusText() {
if (this.status === 'syncing') {
return '正在努力同步数据中...';
}
if (this.status === 'error') {
return '同步失败';
}
if (this.status === 'done') {
return '同步完成';
}
return '';
},
},
methods: {
handleClicked() {
if (this.status !== 'error') {
return;
}
this.$emit('retry');
},
},
};
</script>
17 changes: 17 additions & 0 deletions src/components/icons/cloudDone.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<svg
t="1661969156458"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="31215"
width="200"
height="200"
>
<path
d="M874.2 459.6C858 309.2 730.8 192 576 192c-102.4 0-192.6 51.2-246.8 129.4-16.6-6.8-34.8-10.6-53.8-10.6-78.2 0-141.6 68.8-142.8 146.8C52.8 483 0 561 0 643 0 743.4 81.4 832 181.8 832h660.6c100.4 0 181.8-88.6 181.8-189-0.2-89.4-64.8-168.2-150-183.4z m-149.2-34.6L457.6 693.6h-0.2c-3.4 3.4-12.6 11-23.2 11-7.6 0-16.2-4.2-23.4-11.4l-112-112c-3.2-3.2-3.2-8.2 0-11.4l35.6-35.6c1.6-1.6 3.6-2.4 5.6-2.4 2 0 4 0.8 5.6 2.4l88.8 88.8 244-245.8c1.6-1.6 3.6-2.4 5.6-2.4 2.2 0 4.2 0.8 5.6 2.4l35 36.2c3.6 3.4 3.6 8.4 0.4 11.6z"
p-id="31216"
></path>
</svg>
</template>
17 changes: 17 additions & 0 deletions src/components/icons/sync.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<svg
t="1661957351859"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5591"
width="16"
height="16"
>
<path
d="M512 170.666667 512 42.666667 341.333333 213.333333l170.666667 170.666667L512 256c140.8 0 256 115.2 256 256 0 42.666667-12.8 85.333333-29.866667 119.466667l64 64C832 640 853.333333 580.266667 853.333333 512 853.333333 324.266667 699.733333 170.666667 512 170.666667zM512 768c-140.8 0-256-115.2-256-256 0-42.666667 12.8-85.333333 29.866667-119.466667L221.866667 328.533333C192 384 170.666667 443.733333 170.666667 512c0 187.733333 153.6 341.333333 341.333333 341.333333l0 128 170.666667-170.666667-170.666667-170.666667L512 768z"
p-id="5592"
></path>
</svg>
</template>
17 changes: 17 additions & 0 deletions src/components/icons/syncError.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<template>
<svg
t="1661961656027"
class="icon"
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="5947"
width="16"
height="16"
>
<path
d="M128 512c0 93.866667 38.4 179.2 102.4 238.933333L128 853.333333l256 0 0-256-93.866667 93.866667C243.2 648.533333 213.333333 584.533333 213.333333 512c0-110.933333 72.533333-204.8 170.666667-243.2L384 183.466667C238.933333 221.866667 128 354.133333 128 512zM469.333333 725.333333l85.333333 0 0-85.333333-85.333333 0L469.333333 725.333333zM896 170.666667l-256 0 0 256 93.866667-93.866667C780.8 375.466667 810.666667 439.466667 810.666667 512c0 110.933333-72.533333 204.8-170.666667 243.2l0 89.6c145.066667-38.4 256-170.666667 256-328.533333 0-93.866667-38.4-179.2-102.4-238.933333L896 170.666667zM469.333333 554.666667l85.333333 0L554.666667 298.666667l-85.333333 0L469.333333 554.666667z"
p-id="5948"
></path>
</svg>
</template>
76 changes: 76 additions & 0 deletions src/styles/common/sync.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
@keyframes sync-rotate {
0% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}

@keyframes sync-blink {
0% {
opacity: 1;
}
50% {
opacity: 0.42;
}
100% {
opacity: 1;
}
}

@keyframes sync-completed {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}

.sync-status {
display: flex;
align-items: center;
height: 28px;
line-height: 28px;
transform: translateY(2px);
margin-left: 12px;
.sync-status__icon {
width: 20px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
path {
fill: @color-primary;
}
}
.sync-status__icon-sync {
animation: sync-rotate linear 0.85s infinite;
}
.sync-status__text {
color: @color-primary;
font-size: 14px;
letter-spacing: 0.025rem;
margin-left: 6px;
}
}

.sync-status--syncing {
animation: sync-blink ease-in-out 1s infinite;
}

.sync-status--completed {
.sync-status__text {
animation-name: sync-completed;
animation-timing-function: ease;
animation-duration: 0.4s;
animation-fill-mode: forwards;
animation-delay: 2.5s;
animation-iteration-count: 1;
}
}

.sync-status--error {
cursor: pointer;
}
1 change: 1 addition & 0 deletions src/styles/main.less
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
@import './common/maintain.less';
@import './common/login.less';
@import './common/userinfo.less';
@import './common/sync.less';

/* Views */

Expand Down
40 changes: 38 additions & 2 deletions src/views/Collection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<div class="collection-header-title__left">
<span>收藏夹</span>
<span class="count-limit">已用栏位 {{ existedCount }}/{{ COLLECTION_SIZE_LIMIT }}</span>
<SyncStatus v-if="syncStatus" :status="syncStatus" ref="syncStatus" @retry="retrySync" />
</div>
<div class="collection-header-close">
<i class="el-icon-close" @click="handleBack"></i>
Expand Down Expand Up @@ -42,7 +43,7 @@
/>
<p class="waterfall-end">
<template v-if="existedCount < COLLECTION_SIZE_LIMIT"
>没有更多收藏了,快去找一些你喜欢的画作吧~</template
>没有更多收藏了,快去寻找一些你喜欢的画作吧~</template
>
<template v-else>收藏夹看起来装不下更多画作了,先整理一下吧~</template>
</p>
Expand All @@ -53,8 +54,10 @@
</template>

<script>
import cloneDeep from 'lodash-es/cloneDeep';
import Waterfall from '../components/common/Waterfall';
import BackToTop from '../components/common/BackToTop';
import SyncStatus from '../components/common/SyncStatus.vue';
import MobileResponsive from '../util/MobileResponsive';
import { getUserCollection, COLLECTION_SIZE_LIMIT, removeFromCollection } from '../util/collection';
import { syncData } from '../util/pixland';
Expand All @@ -63,6 +66,7 @@ export default {
components: {
Waterfall,
BackToTop,
SyncStatus,
},
data() {
return {
Expand All @@ -76,6 +80,7 @@ export default {
notFirstUse: window.localStorage.getItem('pixiviz-user-collect-first-entry') === 'true',
currentCategory: 'default',
collectionLoading: false,
syncStatus: '',
COLLECTION_SIZE_LIMIT,
};
},
Expand Down Expand Up @@ -121,6 +126,9 @@ export default {
} finally {
this.collectionLoading = false;
}
if (this.pixland?.isLogin) {
this.syncRemoteData(true);
}
},
mounted() {
// do scroll
Expand Down Expand Up @@ -208,7 +216,35 @@ export default {
this.waterfallKey += 1;
this.$forceUpdate();
// trigger sync
syncData({ immediate: true });
if (this.pixland?.isLogin) {
this.syncRemoteData();
}
},
async retrySync() {
await this.syncRemoteData(true);
},
async syncRemoteData(doRefresh = false) {
try {
this.syncStatus = 'syncing';
await syncData({ immediate: true });
this.syncStatus = 'done';
} catch (err) {
// eslint-disable-next-line no-console
console.error(err);
this.syncStatus = 'error';
}
if (doRefresh) {
const collection = (await getUserCollection()) || {};
const currentCategoryImages = collection[this.currentCategory] || [];
if (JSON.stringify(currentCategoryImages) === JSON.stringify(this.images)) {
return;
}
this.images = [];
this.waterfallKey += 1;
this.$nextTick(() => {
this.images = cloneDeep(currentCategoryImages);
});
}
},
handleBack() {
this.$router.push('/');
Expand Down

0 comments on commit 2ad31fc

Please sign in to comment.