Skip to content

Commit

Permalink
重构一时爽,BUG 火葬场
Browse files Browse the repository at this point in the history
✨ 支持群 poke 消息以及相关动画/窗口动画
✨ 新增一个没什么用的 bot 状态功能,仅限于开启了 ws 心跳功能的 bot
🐛 修正消息列表在窄布局下的错误,由 3a5483e 损坏
:bug: 修正在 iOS 浏览器下由于通知功能缺失导致通知下游功能损坏的问题
:bug: 修正初次打开由于存储的商城表情未初始化导致的页面卡死问题
:bug: 修正初次打开由于存储的代码未初始导致的页面卡死问题
:bug: 修正由于消息解析器调整公告解析出现错误导致的页面卡死问题,由 c64592d 损坏
:lipstick: 将全局字体限制为非衬线字体,防止在某些浏览器以及 linux 下出现默认为衬线字体的情况
:lipstick: 新增一组常见状态色便于使用
:heavy_plus_sign: 新增依赖:animejs
:green_heart: 发布版本现在会构建一个用于 root 的 web 包便于使用
  • Loading branch information
Stapxs committed Sep 5, 2024
1 parent 3186153 commit 6508e31
Show file tree
Hide file tree
Showing 19 changed files with 263 additions and 58 deletions.
57 changes: 37 additions & 20 deletions .github/workflows/build-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,31 +25,50 @@ jobs:
- name: Init Env
id: step_init
run: |
# 判断是否需要构建 web 版本,检查 push message 中最后一行是否不包含 [not-build-web](默认构建)
if [[ $(git log -1 --pretty=%B) != *"[not-build-web]"* ]]; then
echo 'BUILD_WEB=true'
echo 'BUILD_WEB=true' >> $GITHUB_OUTPUT
else
echo 'BUILD_WEB=false'
echo 'BUILD_WEB=false' >> $GITHUB_OUTPUT
fi
# 判断是否需要构建 electron 版本,检查 push message 中最后一行是否包含 [build-electron]
if [[ $(git log -1 --pretty=%B) == *"[build-electron]"* ]]; then
echo 'BUILD_ELECTRON=true'
echo 'BUILD_ELECTRON=true' >> $GITHUB_OUTPUT
else
echo 'BUILD_ELECTRON=false'
echo 'BUILD_ELECTRON=false' >> $GITHUB_OUTPUT
fi
# 获取版本号
echo VERSION=$(node -p "require('./package.json').version") >> $GITHUB_OUTPUT
# ========================= 构建 Web 版本 =========================
# ========================= 构建 Web 版本 =========================

build-root-web:
name: 构建 Web 版本(根目录)
runs-on: ubuntu-latest
needs: init
steps:
# 拉取代码
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive
persist-credentials: false
# 设置 Node.js 版本
- name: Load Node.js
uses: actions/setup-node@v4
with:
node-version: 18.x
# 更新依赖
- name: Install
run: yarn
# 构建
- name: Build
run: yarn build

# 将 dist 目录压缩为 zip
- name: Zip
run: zip -r Stapxs.QQ.Lite-${{ needs.init.outputs.version }}-web.zip dist

# 上传构建结果
- name: Upload Artifacts
uses: actions/upload-artifact@v4
with:
name: ${{ needs.init.outputs.version }}-web
path: Stapxs.QQ.Lite-${{ needs.init.outputs.version }}-web.zip

# ==================== 构建 Github Pages 版本 =====================
build-pages:
name: 构建 Github Pages 版本
runs-on: ubuntu-latest
needs: init
if: needs.init.outputs.build_web == 'true'
steps:
# 拉取代码
- name: Checkout
Expand Down Expand Up @@ -90,10 +109,8 @@ jobs:
version: ${{ needs.init.outputs.version }}

needs: init
if: needs.init.outputs.build_electron == 'true'

steps:

# 拉取代码
- name: Checkout
uses: actions/checkout@v4
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "stapxs-qq-lite",
"version": "2.8.5",
"version": "2.8.6",
"private": false,
"author": "Stapx Steve [林槐]",
"description": "一个兼容 OneBot 的非官方网页版 QQ 客户端,使用 Vue 重制的全新版本。",
Expand All @@ -19,6 +19,7 @@
"@jakejarrett/gtk-theme": "^2.0.1",
"@stapxs/umami-logger-typescript": "^1.0.12",
"@types/prismjs": "^1.26.4",
"animejs": "^3.2.2",
"axios": "^1.7.2",
"browser-image-compression": "^2.0.0",
"core-js": "^3.8.3",
Expand Down Expand Up @@ -50,6 +51,7 @@
"xss": "^1.0.14"
},
"devDependencies": {
"@types/animejs": "^3.1.12",
"@types/css": "^0.0.33",
"@types/electron-devtools-installer": "^2.2.0",
"@types/jsonpath": "^0.2.3",
Expand Down
11 changes: 11 additions & 0 deletions public/css/append-dark.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
:root {
--color-blue: #316cf4;
--color-green: #408558;
--color-red: #cb444a;
--color-yellow: #f6c344;

--color-bg-blue: #393e47;
--color-bg-green: #3f544a;
--color-bg-red: #523a3c;
--color-bg-yellow: #504b3d;
}
11 changes: 11 additions & 0 deletions public/css/append-light.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
:root {
--color-blue: #316cf4;
--color-green: #408558;
--color-red: #cb444a;
--color-yellow: #f6c344;

--color-bg-blue: #d3e1fc;
--color-bg-green: #d5e6de;
--color-bg-red: #f3d8da;
--color-bg-yellow: #fdf3d1;
}
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<title>Stapxs QQ Lite</title>
<link rel="stylesheet" href="bcui/css/style.css">
<link rel="stylesheet" href="bcui/css/color-light.css">
<link rel="stylesheet" href="css/append-light.css">
</head>
<body>
<noscript>
Expand Down
4 changes: 4 additions & 0 deletions src/assets/css/append/append_vibrancy.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
html, body {
background: transparent;
}

.home-body {
background: rgba(var(--color-card-rgb), 0.6);
}
Expand Down
7 changes: 7 additions & 0 deletions src/assets/css/msg.css
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,10 @@
margin: 0 5px;
}

.note-notify {
transition: border .5s;
border: 1px solid transparent;
}
.note-notify img {
display: inline-block;
width: 1rem;
Expand All @@ -509,6 +513,9 @@
color: var(--color-main);
font-weight: bold;
}
.note.poking > div.note-notify {
border: 1px solid var(--color-main);
}

@media (max-width: 992px) {
/* 消息体 */
Expand Down
35 changes: 35 additions & 0 deletions src/assets/css/options.css
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,41 @@
margin-left: 40px;
}

.bot-status {
background: var(--color-card-1);
transition: background .3s;
padding: 10px;
margin-top: -10px;
margin-bottom: 10px;
border-radius: 7px;
display: flex;
flex-direction: row;
align-items: center;
}
.bot-status.normal {
background: var(--color-bg-green);
}
.bot-status.slow {
background: var(--color-bg-yellow);
}
.bot-status > div {
transition: background .3s;
background: var(--color-main);
width: 0.5rem;
height: 0.5rem;
border-radius: 100%;
margin-right: 10px;
}
.bot-status.normal > div {
background: var(--color-green);
}
.bot-status.slow > div {
background: var(--color-yellow);
}
.bot-status > span {
font-size: 0.85rem;
}

.theme-color-col {
flex-direction: row-reverse !important;
margin-right: 0 !important;
Expand Down
4 changes: 2 additions & 2 deletions src/assets/css/view.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
html, body {
background: var(--color-main);
font-family: 'Arial', 'Helvetica', 'sans-serif';
user-select: none;
overflow: hidden;
height: 100%;
Expand Down Expand Up @@ -384,7 +386,6 @@ textarea:focus {
border-radius: 7px;
transform: translate(0, 0);
transition: background .2s, color .2s, transform .2s;
align-items: center;
}
.friend-body.active {
background: var(--color-main);
Expand Down Expand Up @@ -424,7 +425,6 @@ textarea:focus {
overflow: hidden;
}
.friend-body > div:nth-child(1) {
height: 54px;
flex: unset;
width: 4px;
background: var(--color-main);
Expand Down
3 changes: 3 additions & 0 deletions src/assets/l10n/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,9 @@
"option_dev_restart_tip1": "此操作将在重启应用后生效,现在就要重启吗?",
"option_dev_restart_tip2": "此操作仅供娱乐,将会在下次关闭时恢复。",
"a_inner_script": "这是个内嵌示例脚本,你可以修改它并保存使用。",
"opt_bot_status_normal": "连接正常({timeout} - {step} s)",
"opt_bot_status_slow": "连接延迟({timeout} - {step} s)",
"opt_bot_status_loading": "正在收集连接信息……",

"menu_about": "关于",
"menu_update": "检查更新…",
Expand Down
2 changes: 1 addition & 1 deletion src/components/BulletinBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
.format(data.time) }}</span>
</header>
<div :id="'bulletins-msg-' + index" :class="'body' + (!showAll ? '' : ' all')">
<span @click="textClick" v-html="parseText(data.content)"></span>
<span @click="textClick" v-html="parseText(data.content[0])"></span>
</div>
<span v-show="needShow && !showAll">{{ $t('bulletin_show_tip') }}</span>
<div class="info">
Expand Down
64 changes: 59 additions & 5 deletions src/components/NoticeBody.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
-->

<template>
<div class="note">
<div :id="'notice-' + id" class="note">
<div class="note-recall note-base" v-if="data.notice_type && data.notice_type.indexOf('recall') >= 0">
<a>{{ info.name }}</a>
<span>{{ $t('chat_notice_recall') }}</span>
Expand All @@ -28,7 +28,7 @@
</template>
<span v-else>{{ $t('note_unban', { name: isMe(data.user_id) ? $t('you') : getName(data.user_id) }) }}</span>
</div>
<div v-if="data.sub_type === 'poke'" class="note-notify note-base" v-html="data.str"></div>
<div v-if="data.sub_type === 'poke'" class="note-notify note-base" v-html="data.str + '<div class=\'space\'</div>'"></div>
<div v-if="data.sub_type === 'time'" class="note-time note-base">
<a>{{
Intl.DateTimeFormat(trueLang, getTimeConfig(new Date(data.time * 1000)))
Expand All @@ -39,13 +39,15 @@
</template>

<script lang="ts">
import anime from 'animejs'
import { defineComponent, ref } from 'vue'
import { runtimeData } from '@/function/msg'
import { getTimeConfig, getTrueLang } from '@/function/utils/systemUtil'
export default defineComponent({
name: 'NoticeBody',
props: ['data'],
props: ['data', 'id'],
data() {
return {
trueLang: getTrueLang(),
Expand Down Expand Up @@ -89,9 +91,16 @@ export default defineComponent({
return back
}
},
mounted() {
async mounted() {
let windowInfo = null as { x: number, y: number, width: number, height: number } | null
if(runtimeData.tags.isElectron) {
const reader = runtimeData.reader
if(reader) {
windowInfo = await reader.invoke('win:getWindowInfo')
}
}
// 补全撤回者信息
if (this.info.notice_type && this.info.notice_type.indexOf('recall') >= 0) {
// 补全撤回者信息
if (runtimeData.chatInfo.show.type === 'group') {
const id = this.info.operator_id
// 寻找群成员信息
Expand All @@ -111,6 +120,51 @@ export default defineComponent({
this.info.name = runtimeData.chatInfo.show.name
}
}
// poke 通知创建对应的动画
if(this.info.sub_type === 'poke' && this.info.pokeMe) {
// 给 body 创建一个三段的动画
let item = document.getElementById('app')
if(runtimeData.tags.isElectron) {
item = document.getElementById('notice-' + this.id)
?.getElementsByClassName('space')[0] as HTMLElement
}
if(item) {
const timeLine = anime.timeline({ targets: item })
// 如果窗口小于 500px 播放完整的动画(手机端样式)
if((document.getElementById('app')?.offsetWidth ?? 500) < 500) {
navigator.vibrate([10, 740, 10])
timeLine.add({ translateX: 30, duration: 600, easing: 'cubicBezier(.44,.09,.53,1)' })
.add({ translateX: 0, duration: 150, easing: 'cubicBezier(.44,.09,.53,1)' })
.add({ translateX: [0, 25, 0], duration: 500, easing: 'cubicBezier(.21,.27,.82,.67)'})
.add({ targets: {}, duration: 1000 })
.add({ translateX: 70, duration: 1300, easing: 'cubicBezier(.89,.72,.72,1.13)'})
.add({ translateX: 0, duration: 100, easing: 'easeOutSine'})
}
timeLine.add({ translateX: [-10, 10, -5, 5 , 0], duration: 500, easing: 'cubicBezier(.44,.09,.53,1)' })
timeLine.change = () => {
if(item) {
item.parentElement?.parentElement?.classList.add('poking')
const teansformX = item.style.transform
// teansformX 的数字可能是科学计数法,需要转换为普通数字
let num = Number((teansformX.match(/-?\d+\.?\d*/g) ?? [0])[0])
// 取整
num = Math.round(num)
// 输出 translateX
if(runtimeData.tags.isElectron && windowInfo) {
const reader = runtimeData.reader
if(reader) {
reader.send('win:move', { x: windowInfo.x + num, y: windowInfo.y })
}
}
}
}
timeLine.changeComplete = () => {
if(item) {
item.parentElement?.parentElement?.classList.remove('poking')
}
}
}
}
}
})
</script>
19 changes: 18 additions & 1 deletion src/function/electron/ipc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Store from 'electron-store'
import path from 'path'
import os from 'os'

import { ipcMain, shell, systemPreferences, app, Menu, MenuItemConstructorOptions, Notification as ELNotification } from 'electron'
import { ipcMain, shell, systemPreferences, app, Menu, MenuItemConstructorOptions, Notification as ELNotification, screen as sysScreen } from 'electron'

Check warning on line 5 in src/function/electron/ipc.ts

View workflow job for this annotation

GitHub Actions / lint

'sysScreen' is defined but never used
import { GtkTheme, GtkData } from '@jakejarrett/gtk-theme'
import { runCommand } from './util'
import { win, touchBarInstance } from '@/background'
Expand Down Expand Up @@ -76,6 +76,23 @@ export function regIpcListener() {
ipcMain.on('win:alwaysTop', (event, args) => {
if(win) win.setAlwaysOnTop(args)
})
// 获取窗口信息
ipcMain.handle('win:getWindowInfo', () => {
if(win) {
const [x, y] = win.getPosition()
const [width, height] = win.getSize()
return {
x: x, y: y,
width: width, height: height
}
}
})
// 移动窗口位置
ipcMain.on('win:move', (event, point) => {
if(win) {
win.setPosition(point.x, point.y)
}
})
// 保存信息
ipcMain.on('sys:store', (event, arg) => {
store.set(arg.key, arg.value)
Expand Down
Loading

0 comments on commit 6508e31

Please sign in to comment.