Implement selecting and favorite (fix #26)
parent
bee28095fa
commit
bdc964d2ee
|
@ -102,6 +102,14 @@
|
||||||
{{ t('memories', 'Delete') }}
|
{{ t('memories', 'Delete') }}
|
||||||
</NcActionButton>
|
</NcActionButton>
|
||||||
</NcActions>
|
</NcActions>
|
||||||
|
<NcActions>
|
||||||
|
<NcActionButton
|
||||||
|
:aria-label="t('memories', 'Toggle Favorite')"
|
||||||
|
@click="favoriteSelection"
|
||||||
|
class="icon-favorite">
|
||||||
|
{{ t('memories', 'Toggle Favorite') }}
|
||||||
|
</NcActionButton>
|
||||||
|
</NcActions>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -932,6 +940,38 @@ export default class Timeline extends Mixins(GlobalMixin) {
|
||||||
}
|
}
|
||||||
await dav.downloadFilesByIds(Array.from(this.selection.keys()));
|
await dav.downloadFilesByIds(Array.from(this.selection.keys()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if all files selected currently are favorites
|
||||||
|
*/
|
||||||
|
allSelectedFavorites() {
|
||||||
|
return Array.from(this.selection.values()).every(p => p.flag & this.c.FLAG_IS_FAVORITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorite the currently selected photos
|
||||||
|
*/
|
||||||
|
async favoriteSelection() {
|
||||||
|
try {
|
||||||
|
const val = !this.allSelectedFavorites();
|
||||||
|
this.loading++;
|
||||||
|
for await (const favIds of dav.favoriteFilesByIds(Array.from(this.selection.keys()), val)) {
|
||||||
|
favIds.forEach(id => {
|
||||||
|
const photo = this.selection.get(id);
|
||||||
|
if (!photo) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val) {
|
||||||
|
photo.flag |= this.c.FLAG_IS_FAVORITE;
|
||||||
|
} else {
|
||||||
|
photo.flag &= ~this.c.FLAG_IS_FAVORITE;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
this.loading--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -265,3 +265,69 @@ export async function downloadFilesByIds(fileIds: number[]) {
|
||||||
const fileInfos = await getFiles(fileIds);
|
const fileInfos = await getFiles(fileIds);
|
||||||
await downloadFiles(fileInfos.map(f => f.filename));
|
await downloadFiles(fileInfos.map(f => f.filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorite a file
|
||||||
|
* https://github.com/nextcloud/photos/blob/7687e214f9b0f71a2cc73778b8b22ab781490a3b/src/services/FileActions.js
|
||||||
|
*
|
||||||
|
* @param fileName - The file's name
|
||||||
|
* @param favoriteState - The new favorite state
|
||||||
|
*/
|
||||||
|
export async function favoriteFile(fileName: string, favoriteState: boolean) {
|
||||||
|
let encodedPath = encodePath(fileName)
|
||||||
|
while (encodedPath[0] === '/') {
|
||||||
|
encodedPath = encodedPath.substring(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return axios.post(
|
||||||
|
`${generateUrl('/apps/files/api/v1/files/')}${encodedPath}`,
|
||||||
|
{
|
||||||
|
tags: favoriteState ? ['_$!<Favorite>!$_'] : [],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
} catch (error) {
|
||||||
|
console.error(t('memories', 'Failed to favorite {fileName}.', { fileName }), error)
|
||||||
|
showError(t('memories', 'Failed to favorite {fileName}.', { fileName }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favorite all files in a given list of Ids
|
||||||
|
*
|
||||||
|
* @param fileIds list of file ids
|
||||||
|
* @param favoriteState the new favorite state
|
||||||
|
* @returns generator of lists of file ids that were state-changed
|
||||||
|
*/
|
||||||
|
export async function* favoriteFilesByIds(fileIds: number[], favoriteState: boolean) {
|
||||||
|
const fileIdsSet = new Set(fileIds);
|
||||||
|
|
||||||
|
if (fileIds.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get files data
|
||||||
|
let fileInfos: any[] = [];
|
||||||
|
try {
|
||||||
|
fileInfos = await getFiles(fileIds.filter(f => f));
|
||||||
|
} catch (e) {
|
||||||
|
showError(t('memories', 'Failed to favorite files.'));
|
||||||
|
console.error('Failed to get file info for files to favorite', fileIds, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Favorite each file
|
||||||
|
fileInfos = fileInfos.filter((f) => fileIdsSet.has(f.fileid));
|
||||||
|
const calls = fileInfos.map((fileInfo) => async () => {
|
||||||
|
try {
|
||||||
|
await favoriteFile(fileInfo.filename, favoriteState);
|
||||||
|
return fileInfo.fileid as number;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(t('memories', 'Failed to favorite {fileName}.', fileInfo), error);
|
||||||
|
showError(t('memories', 'Failed to favorite {fileName}.', fileInfo));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
yield* runInParallel(calls, 10);
|
||||||
|
}
|
Loading…
Reference in New Issue