Skip to content

Commit

Permalink
增加导出动态封面和头像框
Browse files Browse the repository at this point in the history
  • Loading branch information
OToNaShiAKi committed Apr 5, 2023
1 parent 459d09b commit 5c0c46a
Show file tree
Hide file tree
Showing 13 changed files with 109 additions and 36 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "material-douden-tool",
"version": "1.2.1",
"version": "1.2.2",
"private": true,
"author": "濯墨",
"scripts": {
Expand Down
Binary file added public/images/badge.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 27 additions & 3 deletions src/components/HonourAvatar.vue
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
<template>
<v-avatar class="honour-avatar" :size="size">
<v-img :src="avatar">
<v-img :src="avatar" content-class="relative">
<template v-slot:placeholder>
<v-icon>mdi-account-cancel</v-icon>
</template>
</v-img>
<img
v-if="sponsor"
src="/images/badge.png"
class="badge"
:style="{ width: badge, height: badge }"
/>
</v-avatar>
</template>

Expand All @@ -13,7 +19,25 @@ import { mapState } from "vuex";
export default {
name: "HonourAvatar",
computed: { ...mapState(["avatar"]) },
props: { size: { type: Number, default: 48 } },
computed: { ...mapState(["avatar", "sponsor"]) },
props: {
size: { type: Number, default: 48 },
badge: { type: String, default: "200px" },
},
};
</script>

<style>
.badge {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -48%);
pointer-events: none;
z-index: 100;
border-radius: 0px !important;
}
.v-avatar.honour-avatar {
overflow: visible !important;
}
</style>
7 changes: 6 additions & 1 deletion src/ipc.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,12 @@ ipcMain.handle("Cookie", async (event, cookie, csrf, use = true) => {
const hostname = `${OS.platform().toUpperCase()}:${OS.hostname()}`;
const crypto = MD5(`${result.mid}.${hostname}.${csrf}`);
API.defaults.headers.Cookie = `mid=${result.mid}; hostname=${hostname}; crypto=${crypto};`;
await LoginStatistics(result.name, result.avatar, csrf, Package.version);
result.sponsor = await LoginStatistics(
result.name,
result.avatar,
csrf,
Package.version
);
result.shields = await SubShield(use);
}
return result;
Expand Down
2 changes: 1 addition & 1 deletion src/pages/index/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
hint="Alt+上下键切换已发弹幕 TAB可循环切换前后缀"
>
<template v-slot:prepend>
<HonourAvatar />
<HonourAvatar class="mr-1" badge="60px"/>
</template>
<template v-slot:prepend-inner>
<v-select
Expand Down
6 changes: 6 additions & 0 deletions src/pages/index/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ const ChangeCookie = async (state, cookie) => {
}
ChangeConfig(state, { key: "shields", config: result.shields });
state.avatar = result.avatar;
state.sponsor = result.sponsor;
}
};

Expand Down Expand Up @@ -101,6 +102,7 @@ export default new Vuex.Store({
song: { stamps, singer: "", name: "" },
stamp: -1,
avatar: "",
sponsor: false,
},
mutations: {
ChangeCookie,
Expand All @@ -111,3 +113,7 @@ export default new Vuex.Store({
Notify,
},
});

for (const item of shields) {
!item.mid && ipcRenderer.send("PubShield", item.shield, item.handle);
}
2 changes: 1 addition & 1 deletion src/pages/index/views/Cookie.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default {
this.cookie = result.query;
this.ChangeCookie(this.cookie);
this.Notify("登陆成功");
this.$router.push("/room")
this.$router.push("/room");
} else if (result.data === -2) {
this.code = "";
}
Expand Down
17 changes: 11 additions & 6 deletions src/pages/support/views/Anime.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</v-data-table>
<section class="d-flex align-center flex-wrap">
<v-checkbox
v-for="v of headers.slice(1, 6)"
v-for="v of headers.slice(0, 6)"
:key="v.value"
hide-details
dense
Expand All @@ -55,17 +55,19 @@
dense
label="总时长"
v-model="total"
value="total"
/>
</section>
<v-btn-toggle class="mt-3" dense rounded>
<v-btn icon @click="Excel">
<v-icon>mdi-microsoft-excel</v-icon>
<v-btn-toggle class="my-3" dense rounded>
<v-btn icon :loading="exporting" @click="Word">
<v-icon>mdi-microsoft-word</v-icon>
</v-btn>
<v-btn icon @click="Excel">
<v-icon>mdi-microsoft-word</v-icon>
<v-icon>mdi-microsoft-excel</v-icon>
</v-btn>
</v-btn-toggle>
<p class="caption px-3 mb-0">
仅Word格式支持导出封面图片,同时耗时会比较长。
</p>
</v-container>
</template>

Expand All @@ -77,6 +79,7 @@ export default {
name: "Anime",
data: () => ({
keyword: "",
exporting: false,
headers: [
{ text: "封面", value: "avatar", sortable: false },
{ text: "标题", value: "title" },
Expand Down Expand Up @@ -108,8 +111,10 @@ export default {
shell.openExternal(href);
},
async Word() {
this.exporting = true;
const buffer = await ExportWord(this.comments, this.config, this.total);
ipcRenderer.send("SaveFiles", buffer, `${Date.now()}.docx`);
this.exporting = false;
},
Excel() {
const result = ExportExcel(this.comments, this.config, this.total);
Expand Down
3 changes: 3 additions & 0 deletions src/pages/support/views/Sponsor.vue

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/pages/support/views/Video.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
class="ma-2 rounded-lg"
:key="image.key"
:src="image.src"
content-class="relative"
>
<v-icon
class="thumbnail"
Expand Down Expand Up @@ -182,9 +183,8 @@ video::-webkit-media-controls-timeline {
display: none;
}
.thumbnail {
position: absolute;
position: absolute !important;
right: 0;
bottom: 0;
cursor: pointer;
}
</style>
10 changes: 8 additions & 2 deletions src/plugins/axios.js
Original file line number Diff line number Diff line change
Expand Up @@ -526,9 +526,15 @@ export const GetVideoInfo = async (key) => {

export const LoginStatistics = async (name, avatar, jct, version) => {
try {
return await API.post("/alogin", { name, avatar, jct, version });
const { sponsor = 0 } = await API.post("/alogin", {
name,
avatar,
jct,
version,
});
return sponsor > 0;
} catch (error) {
return null;
return false;
}
};

Expand Down
60 changes: 42 additions & 18 deletions src/util/ExportFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
Document,
ExternalHyperlink,
HeadingLevel,
ImageRun,
Packer,
Paragraph,
SectionType,
Expand All @@ -18,19 +19,44 @@ const Mapping = Object.freeze({
duration_desc: "时长",
time_desc: "发布",
uname: "推荐人",
avatar: "封面",
});

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 190;
canvas.height = 120;

const LoadImage = async (src) => {
const image = new Image(canvas.width, canvas.height);
image.src = src;
const result = await new Promise((resolve) => {
image.addEventListener("load", () => {
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
resolve(canvas.toDataURL("image/jpg"));
});
});
return result;
};

export const ExportWord = async (comments, config, need) => {
let total = 0;
const sections = comments.map((v) => {
const children = config.map((key) => {
let sections = comments.map(async (v) => {
let children = config.map(async (key) => {
let child = new TextRun({
text: v[key],
size: 24,
italics: false,
bold: key === "title",
});
if (key === "bvid")
if (key === "bvid") {
child = new ExternalHyperlink({ children: [child], link: v[key] });
} else if (key === "avatar" && v[key]) {
child = new ImageRun({
data: await LoadImage(v[key]),
transformation: { width: canvas.width, height: canvas.height },
});
}
return new Paragraph({
children: [
new TextRun({
Expand All @@ -43,33 +69,31 @@ export const ExportWord = async (comments, config, need) => {
heading: key === "title" ? HeadingLevel.HEADING_3 : undefined,
});
});
children = await Promise.all(children);
children.push(new Paragraph("\n"));
total += v.duration || 0;
return {
properties: { type: SectionType.CONTINUOUS },
children,
};
});
sections = await Promise.all(sections);
if (need) {
sections.unshift({
const p = new Paragraph({
children: [
new Paragraph({
children: [
new TextRun({
text: `【总时长】`,
bold: true,
italics: false,
}),
new TextRun({
text: FormatDuration(total, true),
italics: false,
}),
],
heading: HeadingLevel.HEADING_4,
new TextRun({
text: `【总时长】`,
bold: true,
italics: false,
}),
new TextRun({
text: FormatDuration(total, true),
italics: false,
}),
new Paragraph("\n"),
],
heading: HeadingLevel.HEADING_4,
});
sections.unshift({ children: [p, new Paragraph("\n")] });
}
const buffer = await Packer.toBuffer(
new Document({ title: "动画鉴赏", sections })
Expand Down
2 changes: 1 addition & 1 deletion src/util/SendComment.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const SendComment = (content, select = [], fix = {}, shield = []) => {
const { [item]: length = CommentLength.default } = CommentLength;
ipcRenderer.send("SendComment", content.slice(0, length), item);
if (content.length > length) {
content = content.slice(length, content.length - suffix.length);
content = content.slice(length, content.length - suffix.trim().length);
SendComment(content, [item], fix);
}
}
Expand Down

0 comments on commit 5c0c46a

Please sign in to comment.