Skip to content

Commit 2aeca50

Browse files
committed
✨ Feature: finish all-select && shift multi-select
ISSUES CLOSED: Molunerfinn#342
1 parent b7cbd50 commit 2aeca50

File tree

2 files changed

+83
-17
lines changed

2 files changed

+83
-17
lines changed

src/renderer/pages/Gallery.vue

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,19 @@
4848
<i slot="suffix" class="el-input__icon el-icon-close" v-if="searchText" @click="cleanSearch" style="cursor: pointer"></i>
4949
</el-input>
5050
</el-col>
51-
<el-col :span="6">
51+
<el-col :span="4">
5252
<div class="item-base copy round" :class="{ active: isMultiple(choosedList)}" @click="multiCopy">
53-
<i class="el-icon-document"></i> 批量复制
53+
复制
5454
</div>
5555
</el-col>
56-
<el-col :span="6">
56+
<el-col :span="4">
5757
<div class="item-base delete round" :class="{ active: isMultiple(choosedList)}" @click="multiRemove">
58-
<i class="el-icon-delete"></i> 批量删除
58+
删除
59+
</div>
60+
</el-col>
61+
<el-col :span="4">
62+
<div class="item-base all-pick round" :class="{ active: filterList.length > 0}" @click="toggleSelectAll">
63+
{{ isAllSelected ? '取消' : '全选' }}
5964
</div>
6065
</el-col>
6166
</el-row>
@@ -82,7 +87,7 @@
8287
<i class="el-icon-document" @click="copy(item)"></i>
8388
<i class="el-icon-edit-outline" @click="openDialog(item)"></i>
8489
<i class="el-icon-delete" @click="remove(item.id)"></i>
85-
<el-checkbox v-model="choosedList[item.id]" class="pull-right" @change=" handleBarActive = true"></el-checkbox>
90+
<el-checkbox v-model="choosedList[item.id]" class="pull-right" @change="(val) => handleChooseImage(val, index)"></el-checkbox>
8691
</div>
8792
</el-col>
8893
</el-row>
@@ -106,7 +111,7 @@
106111
// @ts-ignore
107112
import gallerys from 'vue-gallery'
108113
import pasteStyle from '#/utils/pasteTemplate'
109-
import { Component, Vue } from 'vue-property-decorator'
114+
import { Component, Vue, Watch } from 'vue-property-decorator'
110115
import {
111116
ipcRenderer,
112117
clipboard,
@@ -128,11 +133,13 @@ export default class extends Vue {
128133
}
129134
dialogVisible = false
130135
imgInfo = {
131-
id: null,
136+
id: '',
132137
imgUrl: ''
133138
}
134139
choosedList: IObjT<boolean> = {}
135140
choosedPicBed: string[] = []
141+
lastChoosed: number = -1
142+
isShiftKeyPress: boolean = false
136143
searchText = ''
137144
handleBarActive = false
138145
pasteStyle = ''
@@ -144,12 +151,11 @@ export default class extends Vue {
144151
Custom: 'Custom'
145152
}
146153
picBed: IPicBedType[] = []
147-
beforeRouteEnter (to: any, from: any, next: any) {
148-
next((vm: any) => {
149-
vm.getGallery()
150-
vm.getPasteStyle()
151-
vm.getPicBeds()
152-
})
154+
@Watch('$route')
155+
handleRouteUpdate (to: any, from: any) {
156+
if (from.name === 'gallery') {
157+
this.clearChoosedList()
158+
}
153159
}
154160
created () {
155161
ipcRenderer.on('updateGallery', (event: IpcRendererEvent) => {
@@ -160,12 +166,31 @@ export default class extends Vue {
160166
ipcRenderer.send('getPicBeds')
161167
ipcRenderer.on('getPicBeds', this.getPicBeds)
162168
}
169+
mounted () {
170+
document.addEventListener('keydown', this.handleDetectShiftKey)
171+
document.addEventListener('keyup', this.handleDetectShiftKey)
172+
}
173+
handleDetectShiftKey (event: KeyboardEvent) {
174+
if (event.keyCode === 16) {
175+
this.isShiftKeyPress = !this.isShiftKeyPress
176+
}
177+
}
163178
get filterList () {
164179
return this.getGallery()
165180
}
166181
set filterList (val) {
167182
this.images = val
168183
}
184+
get isAllSelected () {
185+
const values = Object.values(this.choosedList)
186+
if (values.length === 0) {
187+
return false
188+
} else {
189+
return this.filterList.every(item => {
190+
return this.choosedList[item.id!]
191+
})
192+
}
193+
}
169194
getPicBeds (event: IpcRendererEvent, picBeds: IPicBedType[]) {
170195
this.picBed = picBeds
171196
}
@@ -200,6 +225,31 @@ export default class extends Vue {
200225
}
201226
return this.images
202227
}
228+
@Watch('filterList')
229+
handleFilterListChange () {
230+
this.clearChoosedList()
231+
}
232+
handleChooseImage (val: boolean, index: number) {
233+
if (val === true) {
234+
this.handleBarActive = true
235+
if (this.lastChoosed !== -1 && this.isShiftKeyPress) {
236+
let min = Math.min(this.lastChoosed, index)
237+
let max = Math.max(this.lastChoosed, index)
238+
for (let i = min + 1; i < max; i++) {
239+
const id = this.filterList[i].id!
240+
this.$set(this.choosedList, id, true)
241+
}
242+
}
243+
this.lastChoosed = index
244+
}
245+
}
246+
clearChoosedList () {
247+
this.isShiftKeyPress = false
248+
Object.keys(this.choosedList).forEach(key => {
249+
this.choosedList[key] = false
250+
})
251+
this.lastChoosed = -1
252+
}
203253
zoomImage (index: number) {
204254
this.idx = index
205255
this.changeZIndexForGallery(true)
@@ -255,7 +305,7 @@ export default class extends Vue {
255305
})
256306
}
257307
openDialog (item: ImgInfo) {
258-
this.imgInfo.id = item.id
308+
this.imgInfo.id = item.id!
259309
this.imgInfo.imgUrl = item.imgUrl as string
260310
this.dialogVisible = true
261311
}
@@ -291,10 +341,17 @@ export default class extends Vue {
291341
isMultiple (obj: IObj) {
292342
return Object.values(obj).some(item => item)
293343
}
344+
toggleSelectAll () {
345+
const result = !this.isAllSelected
346+
this.filterList.forEach(item => {
347+
this.$set(this.choosedList, item.id!, result)
348+
})
349+
}
294350
multiRemove () {
295351
// choosedList -> { [id]: true or false }; true means choosed. false means not choosed.
296-
if (Object.values(this.choosedList).some(item => item)) {
297-
this.$confirm('将删除刚才选中的图片,是否继续?', '提示', {
352+
const multiRemoveNumber = Object.values(this.choosedList).filter(item => item).length
353+
if (multiRemoveNumber) {
354+
this.$confirm(`将在相册中移除刚才选中的 ${multiRemoveNumber} 张图片,是否继续?`, '提示', {
298355
confirmButtonText: '确定',
299356
cancelButtonText: '取消',
300357
type: 'warning'
@@ -307,7 +364,8 @@ export default class extends Vue {
307364
this.$db.removeById('uploaded', key)
308365
}
309366
})
310-
this.choosedList = {}
367+
this.clearChoosedList()
368+
this.choosedList = {} // 只有删除才能将这个置空
311369
this.getGallery()
312370
const obj = {
313371
title: '操作结果',
@@ -400,6 +458,13 @@ export default class extends Vue {
400458
cursor pointer
401459
background #F15140
402460
color #fff
461+
&.all-pick
462+
cursor not-allowed
463+
background #69C282
464+
&.active
465+
cursor pointer
466+
background #44B363
467+
color #fff
403468
#gallery-view
404469
position relative
405470
.round

src/universal/types/types.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ interface ImgInfo {
4444
height?: number
4545
extname?: string
4646
imgUrl?: string
47+
id?: string
4748
[propName: string]: any
4849
}
4950

0 commit comments

Comments
 (0)