Replaced base64 loading of images with blob, small fixes

This commit is contained in:
Mutzi 2022-09-04 00:11:11 +02:00
parent 95f921554b
commit d4ac3db189
7 changed files with 23 additions and 54 deletions

View File

@ -57,7 +57,7 @@ namespace api {
std::string code = create_totp_qrcode(user, b32_secret); std::string code = create_totp_qrcode(user, b32_secret);
cbk(dto::Responses::get_tfa_setup_res(b32_secret, code)); cbk(dto::Responses::get_tfa_setup_res(b32_secret, code));
} }
} catch (const std::exception& e) { } catch (const std::exception&) {
cbk(dto::Responses::get_badreq_res("Validation error")); cbk(dto::Responses::get_badreq_res("Validation error"));
} }
} }

View File

@ -90,7 +90,6 @@ public:
METHOD_ADD(fs::download, "/download", drogon::Post, "Login"); METHOD_ADD(fs::download, "/download", drogon::Post, "Login");
METHOD_ADD(fs::download_multi, "/download_multi", drogon::Post, "Login"); METHOD_ADD(fs::download_multi, "/download_multi", drogon::Post, "Login");
METHOD_ADD(fs::download_preview, "/download_preview/{}", drogon::Get, "Login"); METHOD_ADD(fs::download_preview, "/download_preview/{}", drogon::Get, "Login");
METHOD_ADD(fs::download_base64, "/download_base64/{}", drogon::Get, "Login");
METHOD_ADD(fs::get_type, "/get_type/{}", drogon::Get, "Login"); METHOD_ADD(fs::get_type, "/get_type/{}", drogon::Get, "Login");
METHOD_LIST_END METHOD_LIST_END
@ -124,7 +123,6 @@ public:
void download(req_type, cbk_type); void download(req_type, cbk_type);
void download_multi(req_type, cbk_type); void download_multi(req_type, cbk_type);
void download_preview(req_type, cbk_type, uint64_t node); void download_preview(req_type, cbk_type, uint64_t node);
void download_base64(req_type, cbk_type, uint64_t node);
void get_type(req_type, cbk_type, uint64_t node); void get_type(req_type, cbk_type, uint64_t node);
}; };

View File

@ -554,28 +554,6 @@ namespace api {
cbk(dto::Responses::get_download_base64_res("data:image/png;base64," + Botan::base64_encode(image))); cbk(dto::Responses::get_download_base64_res("data:image/png;base64," + Botan::base64_encode(image)));
} }
void fs::download_base64(req_type req, cbk_type cbk, uint64_t node) {
db::User user = dto::get_user(req);
auto inode = get_node_and_validate(user, node);
if (!inode.has_value())
return cbk(dto::Responses::get_badreq_res("Unknown node"));
std::filesystem::path p("./files"), name(inode->getValueOfName());
p /= std::to_string(inode->getValueOfId());
try {
std::string mime = mime_type_map.at(name.extension().string());
std::ifstream file(p, std::ios::in | std::ios::binary);
std::vector<uint8_t> content((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
cbk(dto::Responses::get_download_base64_res("data:" + mime + ";base64," + Botan::base64_encode(content)));
} catch (const std::exception&) {
cbk(dto::Responses::get_badreq_res("Invalid file type"));
}
}
void fs::get_type(req_type req, cbk_type cbk, uint64_t node){ void fs::get_type(req_type req, cbk_type cbk, uint64_t node){
db::User user = dto::get_user(req); db::User user = dto::get_user(req);

View File

@ -22,9 +22,9 @@ namespace dto {
namespace Responses { namespace Responses {
struct GetUsersEntry { struct GetUsersEntry {
GetUsersEntry(int id, bool gitlab, bool tfa, std::string name, db::UserRole role) GetUsersEntry(uint64_t id, bool gitlab, bool tfa, std::string name, db::UserRole role)
: id(id), gitlab(gitlab), tfa(tfa), name(std::move(name)), role(role) {} : id(id), gitlab(gitlab), tfa(tfa), name(std::move(name)), role(role) {}
int id; uint64_t id;
bool gitlab, tfa; bool gitlab, tfa;
std::string name; std::string name;
db::UserRole role; db::UserRole role;

View File

@ -73,12 +73,6 @@ export const download_preview = (
): Promise<Responses.DownloadBase64 | Responses.Error> => ): Promise<Responses.DownloadBase64 | Responses.Error> =>
get_token(`/api/fs/download_preview/${node}`, token); get_token(`/api/fs/download_preview/${node}`, token);
export const download_base64 = (
token: string,
node: number
): Promise<Responses.DownloadBase64 | Responses.Error> =>
get_token(`/api/fs/download_base64/${node}`, token);
export const get_type = ( export const get_type = (
token: string, token: string,
node: number node: number

View File

@ -1,22 +1,24 @@
import { ref } from 'vue'; import { ref } from 'vue';
import { NProgress } from 'naive-ui'; import { NProgress } from 'naive-ui';
import filesize from 'filesize'; import filesize from 'filesize';
import { Music, Video } from '@vicons/carbon'; import { Music, Video, Image } from '@vicons/carbon';
import type { DialogApiInjection } from 'naive-ui/es/dialog/src/DialogProvider'; import type { DialogApiInjection } from 'naive-ui/es/dialog/src/DialogProvider';
export default function createAudioVideoDialog( export default function createBlobDialog(
dialog: DialogApiInjection, dialog: DialogApiInjection,
audio: boolean,
video: boolean video: boolean
) { ) {
const progress = ref(0); const progress = ref(0);
const total = ref(1); const total = ref(1);
const percentage = ref(0); const percentage = ref(0);
const dia = dialog.create({ const dia = dialog.create({
title: video ? 'Loading video...' : 'Loading audio...', title:
'Loading ' + (video ? 'video' : audio ? 'audio' : 'image') + '...',
closable: false, closable: false,
closeOnEsc: false, closeOnEsc: false,
maskClosable: false, maskClosable: false,
icon: () => (video ? <Video /> : <Music />), icon: () => (video ? <Video /> : audio ? <Music /> : <Image />),
content: () => ( content: () => (
<NProgress <NProgress
type="line" type="line"

View File

@ -4,7 +4,7 @@ import { inject, ref, watch } from 'vue';
import { Download, Play } from '@vicons/carbon'; import { Download, Play } from '@vicons/carbon';
import { useDialog, NGrid, NGi, NButton, NImage, NSpin, NIcon } from 'naive-ui'; import { useDialog, NGrid, NGi, NButton, NImage, NSpin, NIcon } from 'naive-ui';
import { check_token, FS, isErrorResponse } from '@/api'; import { check_token, FS, isErrorResponse } from '@/api';
import createAudioVideoDialog from '@/components/FileViewer/AudioVideoDownload'; import createBlobDialog from '@/components/FileViewer/BlobDownload';
import axios from 'axios'; import axios from 'axios';
const props = defineProps<{ const props = defineProps<{
@ -31,11 +31,12 @@ async function download() {
FS.download_file(token, props.node.id); FS.download_file(token, props.node.id);
} }
async function loadAudioOrVideo() { async function loadContent() {
const token = await check_token(jwt); const token = await check_token(jwt);
if (!token) return; if (!token) return;
const { progress, total, percentage, dia } = createAudioVideoDialog( const { progress, total, percentage, dia } = createBlobDialog(
dialog, dialog,
fileType.value === fileTypes.AUDIO,
fileType.value === fileTypes.VIDEO fileType.value === fileTypes.VIDEO
); );
total.value = props.node.size ?? 1; total.value = props.node.size ?? 1;
@ -63,10 +64,8 @@ async function getType(node: Responses.GetNode) {
const resp = await FS.get_type(token, node.id); const resp = await FS.get_type(token, node.id);
if (isErrorResponse(resp)) return; if (isErrorResponse(resp)) return;
if (resp.type.startsWith('image')) { if (resp.type.startsWith('image')) {
const dataResp = await FS.download_base64(token, node.id);
if (isErrorResponse(dataResp)) return;
src.value = dataResp.data;
fileType.value = fileTypes.IMAGE; fileType.value = fileTypes.IMAGE;
await loadContent();
} }
if (resp.type.startsWith('audio')) fileType.value = fileTypes.AUDIO; if (resp.type.startsWith('audio')) fileType.value = fileTypes.AUDIO;
if (resp.type.startsWith('video')) fileType.value = fileTypes.VIDEO; if (resp.type.startsWith('video')) fileType.value = fileTypes.VIDEO;
@ -95,27 +94,25 @@ watch(
</n-gi> </n-gi>
<n-gi style="text-align: center"> <n-gi style="text-align: center">
<n-spin v-if="fileType === fileTypes.LOADING" size="large" /> <n-spin v-if="fileType === fileTypes.LOADING" size="large" />
<n-image <template v-else-if="fileType !== fileTypes.UNKNOWN">
v-else-if="fileType === fileTypes.IMAGE"
:src="src"
:alt="node.name"
/>
<template
v-else-if="
fileType === fileTypes.VIDEO || fileType === fileTypes.AUDIO
"
>
<video <video
v-if="fileType === fileTypes.VIDEO && src !== ''" v-if="fileType === fileTypes.VIDEO && src !== ''"
:src="src" :src="src"
controls controls
autoplay
/> />
<audio <audio
v-else-if="fileType === fileTypes.AUDIO && src !== ''" v-else-if="fileType === fileTypes.AUDIO && src !== ''"
:src="src" :src="src"
controls controls
autoplay
/> />
<n-button v-else @click="loadAudioOrVideo"> <n-image
v-else-if="fileType === fileTypes.IMAGE && src !== ''"
:src="src"
:alt="node.name"
/>
<n-button v-else-if="fileType !== fileTypes.IMAGE" @click="loadContent">
<template #icon> <template #icon>
<n-icon><Play /></n-icon> <n-icon><Play /></n-icon>
</template> </template>