1
This commit is contained in:
@@ -8,57 +8,162 @@
|
||||
</v-card-item>
|
||||
|
||||
<v-card-text>
|
||||
<v-row justify="center" align="center">
|
||||
<v-col cols="12" md="8" class="text-center">
|
||||
<v-avatar size="120" class="mb-4">
|
||||
<v-img
|
||||
src="https://avatars.githubusercontent.com/u/88357633?v=4"
|
||||
alt="Sunwuyuan"
|
||||
/>
|
||||
</v-avatar>
|
||||
<v-row>
|
||||
<v-col cols="12" md="8" class="mx-auto">
|
||||
<div class="d-flex flex-column align-start">
|
||||
<v-avatar size="120" class="mb-4">
|
||||
<v-img
|
||||
src="https://github.com/Sunwuyuan.png"
|
||||
alt="Sunwuyuan"
|
||||
/>
|
||||
</v-avatar>
|
||||
|
||||
<h2 class="text-h5 mb-2">Classworks</h2>
|
||||
<p class="text-body-1 mb-4">
|
||||
由 <a
|
||||
href="https://github.com/sunwuyuan"
|
||||
target="_blank"
|
||||
class="text-decoration-none font-weight-medium"
|
||||
>Sunwuyuan</a> 开发
|
||||
</p>
|
||||
<h2 class="text-h5 mb-2">Classworks</h2>
|
||||
<p class="text-body-1 mb-4">适用于班级大屏的作业板小工具</p>
|
||||
|
||||
<div class="d-flex gap-2 flex-wrap mb-6">
|
||||
<v-btn
|
||||
color="red"
|
||||
variant="tonal"
|
||||
href="https://github.com/ClassworksDev/Classworks/issues"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-bug"
|
||||
>
|
||||
报告问题
|
||||
</v-btn>
|
||||
<v-btn
|
||||
variant="text"
|
||||
href="https://github.com/ClassworksDev/Classworks"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-github"
|
||||
>
|
||||
前端
|
||||
</v-btn>
|
||||
<v-btn
|
||||
variant="text"
|
||||
href="https://github.com/ClassworksDev/ClassworksServer"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-github"
|
||||
>
|
||||
后端
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-divider class="mb-4 w-100"></v-divider>
|
||||
|
||||
<h3 class="text-h6 mb-2">备注与致谢</h3>
|
||||
<v-list class="mb-4 bg-transparent">
|
||||
<v-list-item
|
||||
href="https://github.com/EnderWolf006/HomeworkBoard"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
本项目受到 HomeworkBoard 的启发而开发
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
感谢 EnderWolf006 (@EnderWolf) fhzit(@Hellofhz) KeyFac
|
||||
等人的贡献
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
href="https://houlangs.com"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
Classworks 由<strong>厚浪云</strong>提供
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
长江后浪推前浪 浮事新人换旧人
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
href="https://zerocat.houlangs.com"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
感谢 ZeroCat 社区的开发者们
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
新一代,开源,编程社区
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-divider class="ma-1"></v-divider>
|
||||
<v-list-item
|
||||
href="https://github.com/HUSX100/IslandCaller"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
本项目与 IslandCaller 无关
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
IslandCaller 是由 HUSX100 开发的基于 ClassIsland
|
||||
提醒服务的轻量级点名器
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
<v-list-item
|
||||
href="https://classisland.tech"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
本项目与 ClassIsland 无关
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
ClassIsland 是由 HelloWRC
|
||||
开发的适用于班级大屏的课表信息显示工具
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
|
||||
<div class="d-flex justify-center gap-2 flex-wrap">
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
href="https://github.com/ClassworksDev/Classworks"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-github"
|
||||
variant="text"
|
||||
class="mb-4"
|
||||
prepend-icon="mdi-package-variant"
|
||||
@click="showDeps = true"
|
||||
>
|
||||
前端 GitHub
|
||||
查看使用的第三方库
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
href="https://github.com/ClassworksDev/ClassworksServer"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-github"
|
||||
|
||||
<v-dialog
|
||||
v-model="showDeps"
|
||||
transition="dialog-bottom-transition"
|
||||
fullscreen
|
||||
>
|
||||
后端 GitHub
|
||||
</v-btn>
|
||||
<v-btn
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
href="https://github.com/ClassworksDev/Classworks/issues"
|
||||
target="_blank"
|
||||
prepend-icon="mdi-bug"
|
||||
>
|
||||
报告问题
|
||||
</v-btn>
|
||||
<v-card
|
||||
><v-toolbar>
|
||||
<v-btn icon="mdi-close" @click="showDeps = false"></v-btn>
|
||||
<v-toolbar-title>使用的第三方库</v-toolbar-title>
|
||||
<v-spacer></v-spacer>
|
||||
</v-toolbar>
|
||||
<v-card-text>
|
||||
<v-list>
|
||||
<v-list-item
|
||||
v-for="dep in Dependencies"
|
||||
:key="dep.name"
|
||||
:href="'https://www.npmjs.com/package/' + dep.name"
|
||||
target="_blank"
|
||||
append-icon="mdi-link"
|
||||
>
|
||||
<v-list-item-title>
|
||||
{{ dep.name }}
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
v{{ dep.version }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-dialog>
|
||||
|
||||
<p class="text-caption text-medium-emphasis">
|
||||
Copyright © {{ new Date().getFullYear() }} Sunwuyuan
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<p class="mt-4 text-caption text-medium-emphasis">
|
||||
GPL License © 2024
|
||||
</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-card-text>
|
||||
@@ -66,7 +171,57 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, onMounted } from "vue";
|
||||
import packageJson from "../../../package.json";
|
||||
|
||||
export default {
|
||||
name: 'AboutCard'
|
||||
}
|
||||
name: "AboutCard",
|
||||
setup() {
|
||||
const Dependencies = ref([]);
|
||||
const showDeps = ref(false); // 添加对话框显示状态
|
||||
|
||||
const loadDependencies = () => {
|
||||
try {
|
||||
// 合并 dependencies 和 devDependencies
|
||||
const allDependencies = {
|
||||
...(packageJson.dependencies || {}),
|
||||
...(packageJson.devDependencies || {}),
|
||||
};
|
||||
|
||||
// 转换为数组并过滤掉不需要显示的依赖
|
||||
const deps = Object.entries(allDependencies).map(([name, version]) => ({
|
||||
name,
|
||||
version: version.replace(/[\^~]/g, ""),
|
||||
description: getDependencyDescription(name),
|
||||
}));
|
||||
|
||||
Dependencies.value = deps;
|
||||
} catch (error) {
|
||||
console.error("加载依赖信息失败:", error);
|
||||
Dependencies.value = [];
|
||||
}
|
||||
};
|
||||
|
||||
const getDependencyDescription = (name) => {
|
||||
const descriptions = {
|
||||
vue: "渐进式 JavaScript 框架",
|
||||
vuetify: "材料设计组件框架",
|
||||
axios: "Promise 基础的 HTTP 客户端",
|
||||
pinia: "Vue 状态管理库",
|
||||
"vue-router": "Vue.js 官方路由管理器",
|
||||
"@vitejs/plugin-vue": "Vite 的 Vue 插件",
|
||||
};
|
||||
return descriptions[name] || "";
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadDependencies();
|
||||
});
|
||||
|
||||
return {
|
||||
Dependencies,
|
||||
showDeps,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<settings-card
|
||||
border
|
||||
title="回声洞"
|
||||
icon="mdi-thought-bubble"
|
||||
@click="handleClick"
|
||||
>
|
||||
<v-card-text>
|
||||
<div ref="typewriter" class="typewriter-text"></div>
|
||||
<div ref="sourceWriter" class="source-text text-caption text-grey"></div>
|
||||
</v-card-text>
|
||||
<div class="d-flex align-center">
|
||||
<transition name="fade">
|
||||
<div v-if="currentQuote?.contributor" class="contributor">
|
||||
<v-chip>
|
||||
<v-avatar start>
|
||||
<v-img
|
||||
:src="`https://github.com/${currentQuote.contributor}.png`"
|
||||
></v-img> </v-avatar
|
||||
>{{ currentQuote.contributor }}
|
||||
</v-chip>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
</settings-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Typewriter from "typewriter-effect/dist/core";
|
||||
import quotes from "@/data/echoChamber.json";
|
||||
import SettingsCard from "@/components/SettingsCard.vue";
|
||||
|
||||
export default {
|
||||
name: "EchoChamberCard",
|
||||
components: { SettingsCard },
|
||||
data() {
|
||||
return {
|
||||
typewriter: null,
|
||||
sourceWriter: null,
|
||||
currentQuote: {
|
||||
text: this.INITIAL_TEXT,
|
||||
author: this.INITIAL_SOURCE,
|
||||
},
|
||||
showCopySuccess: false,
|
||||
hasClicked: false,
|
||||
INITIAL_TEXT: "点击此处可以查看 Classworks 用户群里沙雕群友们的发言",
|
||||
INITIAL_SOURCE: "点击后会复制当前句子到剪贴板中",
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.initTypewriters();
|
||||
},
|
||||
methods: {
|
||||
getRandomQuote() {
|
||||
const index = Math.floor(Math.random() * quotes.quotes.length);
|
||||
return quotes.quotes[index];
|
||||
},
|
||||
initTypewriters() {
|
||||
// 主文本打字机
|
||||
this.typewriter = new Typewriter(this.$refs.typewriter, {
|
||||
delay: 50,
|
||||
deleteSpeed: 30,
|
||||
loop: false,
|
||||
});
|
||||
|
||||
// 来源文本打字机
|
||||
this.sourceWriter = new Typewriter(this.$refs.sourceWriter, {
|
||||
delay: 30,
|
||||
deleteSpeed: 20,
|
||||
loop: false,
|
||||
cursor: "",
|
||||
});
|
||||
|
||||
// 显示初始提示
|
||||
this.typewriter.typeString(this.INITIAL_TEXT).start();
|
||||
this.sourceWriter.typeString(this.INITIAL_SOURCE).start();
|
||||
},
|
||||
|
||||
typeQuote(quote) {
|
||||
this.typewriter.deleteAll(30).typeString(quote.text).start();
|
||||
|
||||
if (quote.author) {
|
||||
this.sourceWriter.deleteAll(20).typeString(`${quote.author}`).start();
|
||||
}
|
||||
},
|
||||
|
||||
refreshQuote() {
|
||||
this.currentQuote = this.getRandomQuote();
|
||||
this.typeQuote(this.currentQuote);
|
||||
},
|
||||
|
||||
async handleClick() {
|
||||
if (!this.hasClicked) {
|
||||
this.hasClicked = true;
|
||||
this.currentQuote = this.getRandomQuote();
|
||||
}
|
||||
await this.copyToClipboard();
|
||||
this.refreshQuote();
|
||||
},
|
||||
|
||||
async copyToClipboard() {
|
||||
if (!this.currentQuote) return;
|
||||
|
||||
const quote = this.currentQuote;
|
||||
const text = `${quote.text}\n${
|
||||
quote.author ? `作者:${quote.author}` : ""
|
||||
}\n${quote.contributor ? `贡献者:${quote.contributor}` : ""}${
|
||||
quote.link
|
||||
? `\n来源:${quote.link}`
|
||||
: quote.contributor
|
||||
? "\n来源:https://github.com/" + quote.contributor
|
||||
: ""
|
||||
}`;
|
||||
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
this.showCopySuccess = true;
|
||||
} catch (err) {
|
||||
console.error("复制失败:", err);
|
||||
}
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.typewriter) {
|
||||
this.typewriter.stop();
|
||||
}
|
||||
if (this.sourceWriter) {
|
||||
this.sourceWriter.stop();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.source-text {
|
||||
opacity: 0.7;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.contributor {
|
||||
opacity: 0.7;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.fade-enter-active,
|
||||
.fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.fade-enter-from,
|
||||
.fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@
|
||||
<theme-settings-card border />
|
||||
</v-col>
|
||||
|
||||
|
||||
<!-- 开发者选项卡片 -->
|
||||
<v-col :cols="12" :md="settings.developer.enabled ? 12 : 6">
|
||||
<settings-card
|
||||
@@ -133,6 +134,10 @@
|
||||
/>
|
||||
</v-col>
|
||||
|
||||
<!-- 添加回声洞卡片 -->
|
||||
<v-col cols="12">
|
||||
<echo-chamber-card border />
|
||||
</v-col>
|
||||
<!-- 关于卡片 -->
|
||||
<v-col cols="12">
|
||||
<about-card />
|
||||
@@ -152,6 +157,7 @@ import RefreshSettingsCard from '@/components/settings/cards/RefreshSettingsCard
|
||||
import DisplaySettingsCard from '@/components/settings/cards/DisplaySettingsCard.vue';
|
||||
import DataProviderSettingsCard from '@/components/settings/cards/DataProviderSettingsCard.vue';
|
||||
import ThemeSettingsCard from '@/components/settings/cards/ThemeSettingsCard.vue';
|
||||
import EchoChamberCard from '@/components/settings/cards/EchoChamberCard.vue';
|
||||
import {
|
||||
getSetting,
|
||||
setSetting,
|
||||
@@ -177,7 +183,8 @@ export default {
|
||||
StudentListCard,
|
||||
AboutCard,
|
||||
DataProviderSettingsCard,
|
||||
ThemeSettingsCard
|
||||
ThemeSettingsCard,
|
||||
EchoChamberCard
|
||||
},
|
||||
setup() {
|
||||
const { mobile } = useDisplay();
|
||||
|
||||
Reference in New Issue
Block a user