Skip to content

Commit 52d8dd9

Browse files
i18n: update
feat: fix a bit virtual scroll but still stuttering
1 parent ab16d1f commit 52d8dd9

File tree

19 files changed

+182
-66
lines changed

19 files changed

+182
-66
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,5 @@ Pull Requests: [Pull Requests](https://github.com/hexadecimal233/cloudie/pulls)
8787
- [ ] Make tags work
8888
- [ ] add share modal
8989
- [ ] add tooltips to icon-only buttons
90+
- [ ] watch immediate options
9091
-->

src/assets/i18n/en.json

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"removeSelected": "Remove Selected"
7979
},
8080
"downloads": {
81+
"actions": "Actions",
8182
"deleteSelected": "Delete Selected",
8283
"allDownloads": "All Downloads",
8384
"downloading": "Downloading",
@@ -86,7 +87,7 @@
8687
"failed": "Failed",
8788
"paused": "Paused",
8889
"pending": "Pending",
89-
"songInfo": "Song Info",
90+
"track": "Track",
9091
"playlist": "Playlist",
9192
"addedTime": "Added Time",
9293
"origName": "Original Name",
@@ -99,7 +100,7 @@
99100
"search": "Search",
100101
"selected": "Selected: {count}",
101102
"searchResult": "1 item found | {count} items found",
102-
"song": "Song",
103+
"track": "Track",
103104
"genre": "Genre",
104105
"duration": "Duration",
105106
"downloadability": "Downloadability",
@@ -112,7 +113,12 @@
112113
"addToPlaylist": "Add To Playlist",
113114
"addToListening": "Add To Listening List",
114115
"deleteFromPlaylist": "Delete from Playlist",
115-
"tags": "Tags"
116+
"tags": "Tags",
117+
"tracks": "{count} Tracks",
118+
"listenAll": "Listen All",
119+
"addAll": "Add All",
120+
"listenSelected": "Listen Selected",
121+
"openInNew": "Open in New Tab"
116122
},
117123
"library": {
118124
"playlist": "Playlist",
@@ -121,6 +127,8 @@
121127
"madeFor": "Made for {name}"
122128
},
123129
"common": {
130+
"copy": "Copy",
131+
"error": "Error",
124132
"loading": "Loading...",
125133
"noMore": "No More",
126134
"loadMore": "Load More",
@@ -130,6 +138,14 @@
130138
"play": "Play"
131139
},
132140
"toasts": {
141+
"likeTrackErr": "Failed to like track",
142+
"likePlaylistErr": "Failed to like playlist",
143+
"likeSystemPlaylistErr": "Cannot like system playlist",
144+
"followUserErr": "Failed to follow user",
145+
"repostTrackErr": "Failed to repost track",
146+
"repostPlaylistErr": "Failed to repost playlist",
147+
"ffmpegNotInstalled": "FFmpeg not installed",
148+
"ok": "OK",
133149
"playlistOpenFailed": "Failed to open playlist",
134150
"downloadFailed": "Download failed",
135151
"loginFailed": "Login failed",
@@ -158,6 +174,7 @@
158174
},
159175
"settings": {
160176
"config": {
177+
"feedStyle": "Feed Style",
161178
"savePath": "Save Path",
162179
"parallelDownloads": "Parallel Downloads",
163180
"playlistSeparateDir": "Separate Playlist Download Folder",
@@ -203,7 +220,28 @@
203220
},
204221
"playlistSelectModal": {
205222
"all": "All",
206-
"create": "Create"
223+
"create": "Create",
224+
"title": "Select Playlist"
225+
},
226+
"full": {
227+
"playlist": {
228+
"tracks": "{count} Tracks",
229+
"duration": "Duration: {duration}"
230+
},
231+
"track": {
232+
"reposted": "Reposted",
233+
"posted": "Posted"
234+
}
235+
},
236+
"comment": {
237+
"placeholder": "Write a comment...",
238+
"post": "Post Comment",
239+
"sortBy": "Sort By:",
240+
"sort": {
241+
"newest": "Newest",
242+
"oldest": "Oldest",
243+
"trackTimestamp": "Track Timestamp"
244+
}
207245
}
208246
}
209247
}

src/assets/i18n/zh-CN.json

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"onTrack": "在单曲"
4646
},
4747
"downloads": {
48+
"actions": "操作",
4849
"deleteSelected": "删除选中",
4950
"allDownloads": "所有下载",
5051
"downloading": "下载中",
@@ -53,10 +54,11 @@
5354
"failed": "失败",
5455
"paused": "已暂停",
5556
"pending": "排队中",
56-
"songInfo": "歌曲信息",
57+
"track": "歌曲",
5758
"playlist": "歌单",
5859
"addedTime": "添加时间",
5960
"origFileName": "原文件名",
61+
"origName": "原文件名",
6062
"status": "状态",
6163
"tag": "添加音频元数据"
6264
},
@@ -65,7 +67,7 @@
6567
"search": "搜索",
6668
"selected": "选中: {count}",
6769
"searchResult": "{count} 项结果",
68-
"song": "歌曲",
70+
"track": "歌曲",
6971
"genre": "流派",
7072
"duration": "时长",
7173
"downloadability": "可下载性",
@@ -78,9 +80,15 @@
7880
"addToListening": "添加到试听列表",
7981
"addToPlaylist": "添加到歌单",
8082
"deleteFromPlaylist": "从歌单中删除",
81-
"tags": "标签"
83+
"tags": "标签",
84+
"tracks": "{count} 首歌曲",
85+
"listenAll": "播放全部",
86+
"addAll": "添加全部",
87+
"listenSelected": "播放选中",
88+
"openInNew": "在新标签页打开"
8289
},
8390
"player": {
91+
"listening": "试听列表",
8492
"ordered-no-repeat": "有序播放 (不循环)",
8593
"ordered": "有序播放",
8694
"single-repeat": "单曲循环",
@@ -94,6 +102,14 @@
94102
"madeFor": "为 {name} 推荐"
95103
},
96104
"toasts": {
105+
"likeTrackErr": "喜欢歌曲失败",
106+
"likePlaylistErr": "喜欢歌单失败",
107+
"likeSystemPlaylistErr": "不能喜欢系统歌单",
108+
"followUserErr": "关注用户失败",
109+
"repostTrackErr": "转发歌曲失败",
110+
"repostPlaylistErr": "转发歌单失败",
111+
"ffmpegNotInstalled": "未安装 FFmpeg",
112+
"ok": "确定",
97113
"playlistOpenFailed": "打开歌单失败",
98114
"downloadFailed": "下载失败",
99115
"loginFailed": "登录失败",
@@ -121,6 +137,8 @@
121137
"noComments": "暂无评论"
122138
},
123139
"common": {
140+
"copy": "复制",
141+
"error": "错误",
124142
"loading": "加载中...",
125143
"noMore": "没有更多了",
126144
"loadMore": "加载更多",
@@ -131,6 +149,7 @@
131149
},
132150
"settings": {
133151
"config": {
152+
"feedStyle": "信息流样式",
134153
"savePath": "保存路径",
135154
"parallelDownloads": "并行下载数量",
136155
"playlistSeparateDir": "将播单下载保存到单独目录",
@@ -143,7 +162,9 @@
143162
"oauthToken": "Soundcloud OAuth 令牌",
144163
"theme": "主题",
145164
"language": "语言",
146-
"noHistory": "禁用播放历史记录"
165+
"noHistory": "禁用播放历史记录",
166+
"bgBlur": "背景模糊",
167+
"bg": "背景"
147168
},
148169
"fileNamingTypes": {
149170
"title": "标题",
@@ -168,7 +189,33 @@
168189
},
169190
"etc": {
170191
"loginSoundcloud": "登录 Soundcloud",
171-
"clearCache": "清除缓存"
192+
"clearCache": "清除缓存",
193+
"invalidSavePath": "无效的保存路径"
194+
}
195+
},
196+
"playlistSelectModal": {
197+
"all": "全部",
198+
"create": "创建",
199+
"title": "选择歌单"
200+
},
201+
"full": {
202+
"playlist": {
203+
"tracks": "{count} 首歌曲",
204+
"duration": "时长: {duration}"
205+
},
206+
"track": {
207+
"reposted": "已转发",
208+
"posted": "已发布"
209+
}
210+
},
211+
"comment": {
212+
"placeholder": "写一条评论...",
213+
"post": "发表评论",
214+
"sortBy": "排序方式:",
215+
"sort": {
216+
"newest": "最新",
217+
"oldest": "最旧",
218+
"trackTimestamp": "歌曲时间戳"
172219
}
173220
},
174221
"search": {

src/components/TitleBar.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const easterStyle = computed(() => {
4040
easterClicks.value = 0
4141
return { animation: "none" }
4242
}
43-
if (easterClicks.value === 4) {
43+
if (easterClicks.value === 4) {
4444
return { animation: "oldschool-blink 0.1s step-end infinite" }
4545
} else {
4646
return { animation: "none" }

src/components/VirtualList.vue

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
<template>
2-
<!-- FIXME: page changes doesnt active re-renderer -->
3-
<div ref="parentRef" class="overflow-auto">
4-
<span> {{`${totalSize} ${items.length} ${virtualRows.length}` }}</span>
5-
<div ref="scrollContainer" :style="{ height: `${totalSize}px`, width: '100%', position: 'relative' }">
6-
<div v-for="virtualRow in virtualRows" :key="virtualRow.index" class="absolute w-full top-0 left-0" :style="{
7-
height: `${virtualRow.size}px`,
8-
transform: `translateY(${virtualRow.start}px)`,
9-
}">
10-
<div :ref="measureElement" class="w-full h-full">
11-
<slot name="item" :item="items[virtualRow.index]" :index="virtualRow.index" />
12-
</div>
13-
</div>
2+
<!-- FIXME: page changes doesnt active re-renderer and they are not unmounting-->
3+
<div ref="parentRef" class="overflow-auto">
4+
<div ref="scrollContainer" :style="{ height: `${totalSize}px`, width: '100%', position: 'relative' }">
5+
<div
6+
class="absolute w-full top-0 left-0" :style="{
7+
transform: `translateY(${virtualRows[0]?.start - rowVirtualizer.options.scrollMargin}px)`,
8+
}">
9+
<div v-for="virtualRow in virtualRows" :data-index="virtualRow.index" :key="virtualRow.index" :ref="estimateSize === defaultEstimateSize ? undefined : measureElement" class="w-full h-full">
10+
<slot name="item" :item="items[virtualRow.index]" :index="virtualRow.index" />
1411
</div>
12+
</div>
1513
</div>
14+
</div>
1615
</template>
1716

1817
<script setup lang="ts">
19-
import { ref, computed, VNodeRef } from "vue"
18+
import { ref, computed } from "vue"
2019
import { useVirtualizer } from "@tanstack/vue-virtual"
2120
2221
const props = defineProps<{
@@ -26,13 +25,14 @@ const props = defineProps<{
2625
2726
const parentRef = ref<HTMLElement | null>(null)
2827
const scrollContainer = ref<HTMLElement | null>(null)
28+
const defaultEstimateSize = (index: number) => 50
2929
3030
const rowVirtualizer = useVirtualizer(
3131
computed(() => {
3232
return {
3333
count: props.items.length, // this should be reactive
3434
getScrollElement: () => parentRef.value,
35-
estimateSize: props.estimateSize || (() => 50), // 提供默认值
35+
estimateSize: props.estimateSize || defaultEstimateSize, // 提供默认值
3636
overscan: 5,
3737
}
3838
}),
@@ -41,14 +41,13 @@ const rowVirtualizer = useVirtualizer(
4141
const virtualRows = computed(() => rowVirtualizer.value.getVirtualItems())
4242
const totalSize = computed(() => rowVirtualizer.value.getTotalSize())
4343
44-
// FIXME: dynamic height not working
4544
const measureElement = (el: any) => {
4645
if (!el) {
4746
return
4847
}
49-
48+
5049
rowVirtualizer.value.measureElement(el)
51-
50+
5251
return undefined
5352
}
5453

src/components/full/FullPlaylist.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@
3838
</div>
3939

4040
<span class="text-sm">
41-
{{ formatMillis(props.playlist.duration) }} <!-- TODO: Time display -->
41+
<p>{{ $t('cloudie.full.playlist.tracks', { count: props.playlist.track_count ?? 0 }) }}</p>
42+
<p>{{ $t('cloudie.full.playlist.duration', { duration: formatMillis(props.playlist.duration ?? 0) }) }}</p>
43+
<!-- TODO: Time display -->
4244
</span>
4345
</div>
4446
</div>

src/components/full/FullTrack.vue

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
{{ streamItem.user.username }}
88
</ULink>
99
<i-mingcute-repeat-line v-if="streamItem.type === 'track-repost'" />
10-
{{ streamItem.type === 'track-repost' ? 'Reposted' : 'Posted' }} a track {{ formatFromNow(streamItem.created_at)
11-
}}
10+
{{ streamItem.type === 'track-repost' ? $t('cloudie.full.track.reposted', { time: formatFromNow(streamItem.created_at) }) : $t('cloudie.full.track.posted', { time: formatFromNow(streamItem.created_at) }) }}
1211
</div>
1312

1413
<RichText v-if="streamItem?.caption" :content="streamItem.caption" class="text-sm line-clamp-1" />

src/components/full/themes/TwitterFullPlaylist.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
</div>
5656
<!-- Added a bit of spacing here for the Twitter style -->
5757
<div class="mt-2 text-xs text-neutral-500">
58-
<p>{{ $t('cloudie.full.playlist.tracks', props.playlist.track_count ?? 0) }}</p>
58+
<p>{{ $t('cloudie.full.playlist.tracks', { count: props.playlist.track_count ?? 0 }) }}</p>
59+
<p>{{ $t('cloudie.full.playlist.duration', { duration: formatMillis(props.playlist.duration ?? 0) }) }}</p>
5960
</div>
6061
</div>
6162
</div>

src/components/mini/MiniPlaylist.vue

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,30 @@
11
<template>
22
<div class="flex items-center gap-3 p-2 rounded-lg hover:bg-accented/50 transition-colors min-w-0 w-full h-18">
33
<div class="flex items-center gap-3 flex-1 min-w-0">
4-
<img :src="artworkUrl" :alt="props.playlist.title" class="size-14 rounded-sm object-cover flex-shrink-0" />
5-
<div class="flex flex-col min-w-0 flex-1">
6-
<UTooltip :text="props.playlist.title">
7-
<ULink :to="`/user-playlist/${props.playlist.id}`"
8-
class="truncate font-bold cursor-pointer max-w-full inline-block text-highlighted">
9-
{{ props.playlist.title }}
10-
</ULink>
11-
</UTooltip>
12-
<UTooltip :text="props.playlist.user.username">
13-
<ULink :to="`/user/${props.playlist.user.id}`"
14-
class="truncate text-sm text-muted cursor-pointer max-w-full inline-block">
15-
{{ props.playlist.user.username }}
16-
</ULink>
17-
</UTooltip>
18-
<p class="truncate text-sm text-muted">{{ (props.playlist.tracks || []).length }} {{ $t("cloudie.trackList.song")
19-
}}</p>
20-
</div>
4+
<img :src="artworkUrl" :alt="props.playlist.title" class="size-14 rounded-sm object-cover flex-shrink-0" />
5+
<div class="flex flex-col min-w-0 flex-1">
6+
<UTooltip :text="props.playlist.title">
7+
<ULink :to="`/user-playlist/${props.playlist.id}`"
8+
class="truncate font-bold cursor-pointer max-w-full inline-block text-highlighted">
9+
{{ props.playlist.title }}
10+
</ULink>
11+
</UTooltip>
12+
<UTooltip :text="props.playlist.user.username">
13+
<ULink :to="`/user/${props.playlist.user.id}`"
14+
class="truncate text-sm text-muted cursor-pointer max-w-full inline-block">
15+
{{ props.playlist.user.username }}
16+
</ULink>
17+
</UTooltip>
18+
<p class="truncate text-sm text-muted"> {{ $t("cloudie.trackList.tracks", {
19+
count: (props.playlist.tracks ||
20+
[]).length})}}</p>
21+
</div>
2122
</div>
2223

2324
<div class="flex items-center gap-2">
24-
<UButton color="neutral" :icon="user.isLikedPlaylist(props.playlist.id) ? 'i-mingcute-heart-fill' : 'i-mingcute-heart-line'" variant="ghost" @click="user.toggleLikePlaylist(props.playlist.id)" />
25+
<UButton color="neutral"
26+
:icon="user.isLikedPlaylist(props.playlist.id) ? 'i-mingcute-heart-fill' : 'i-mingcute-heart-line'"
27+
variant="ghost" @click="user.toggleLikePlaylist(props.playlist.id)" />
2528
</div>
2629
</div>
2730
</template>

0 commit comments

Comments
 (0)