From 29045eef73764d11a4697899cbb3a9a819702cd2 Mon Sep 17 00:00:00 2001 From: stapxs <1007028430.stapx@gmail.com> Date: Mon, 23 Dec 2024 08:43:19 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E5=95=8A=E5=90=A7=E5=90=A7=E5=90=A7?= =?UTF-8?q?=E2=80=A6=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :bug: 调整一些布局错误 <- #156 :wheelchair: iOS:优化在 iPad 上的实体键盘、笔输入结构避让 --- .../src/assets/css/append/append_mobile.css | 32 +++++++++---- src/renderer/src/function/utils/appUtil.ts | 45 ++++++++++++++++--- src/renderer/src/pages/Friends.vue | 14 +++--- src/renderer/src/pages/Messages.vue | 14 +++--- 4 files changed, 76 insertions(+), 29 deletions(-) diff --git a/src/renderer/src/assets/css/append/append_mobile.css b/src/renderer/src/assets/css/append/append_mobile.css index 3dfc464..f0f0fbe 100644 --- a/src/renderer/src/assets/css/append/append_mobile.css +++ b/src/renderer/src/assets/css/append/append_mobile.css @@ -76,8 +76,9 @@ html { .main-body > ul > li > span { display: block !important; } -.main-body > ul > li:first-child { - margin-top: 20px; +.main-body > ul > li { + margin-top: 20px !important; + margin-bottom: 0 !important; } .main-body > ul > li.active > span, .main-body > ul > li.active > svg { @@ -130,7 +131,6 @@ html { } .chat-pan > div.more { padding-bottom: var(--safe-area-bottom); - border-top: 1px solid var(--color-card-2); } .chat-pan > div.more > div:first-child { background: var(--color-card-1); @@ -141,12 +141,20 @@ html { } .chat-pan > div.more > div:nth-child(2) > div:first-child { border-radius: 999px; + height: 40px; + width: 40px; +} +.chat-pan > div.more > div:nth-child(2) > div:first-child > svg { + margin: 8px 13px; + height: 25px; + width: 15px; } .chat-pan > div.more > div:nth-child(2) > div:nth-child(2) { background: transparent; border: 1px solid var(--color-font-2); opacity: 0.7; border-radius: 999px; + height: 40px; } .chat-pan > div.more > div:nth-child(2) > div:nth-child(2) > div { display: none; @@ -187,13 +195,7 @@ html { border-radius: 7px !important; } /* 消息 */ -.message-body > div { - border-radius: 20px; - padding: 7px 15px; - margin-top: 10px; -} .msg-img { - border-radius: 20px; max-height: 40vh; } .msg-img.alone { @@ -258,6 +260,15 @@ html { padding-top: var(--safe-area-top); } +.chat-pan > div.more > div:nth-child(2) > div > form > input, +.chat-pan > div.more > div:nth-child(2) > div > form > textarea { + font-weight: normal; +} + +.friend-list > div:first-child { + padding-top: var(--safe-area-top); +} + @media (max-width: 600px) { .main-body > div { height: calc(100% - 75px - var(--safe-area-top) - var(--safe-area-bottom)); @@ -288,6 +299,9 @@ html { .friend-list .base > svg { height: 1.3rem !important; } + .friend-list > div:first-child { + padding-top: 0; + } .friend-list > div:first-child label { height: calc(1rem + 25px); margin-top: 10px; diff --git a/src/renderer/src/function/utils/appUtil.ts b/src/renderer/src/function/utils/appUtil.ts index 6ddbc02..30b1c22 100644 --- a/src/renderer/src/function/utils/appUtil.ts +++ b/src/renderer/src/function/utils/appUtil.ts @@ -605,14 +605,36 @@ export async function loadMobile() { Keyboard.addListener('keyboardWillShow', async (info: KeyboardInfo) => { const keyboardHeight = info.keyboardHeight - const mainBody = document.getElementsByClassName('main-body')[0] as HTMLElement - if(mainBody) { - // 调整下菜单高度 - const tabBar = document.getElementsByTagName('ul')[0] + // 调整输入框高度 + const sendMore = document.getElementById('send-more') + if(sendMore && keyboardHeight > window.innerHeight / 3) { + sendMore.style.paddingBottom = '10px' + } + + const safeArea = await runtimeData.plantform.pulgins.SafeArea?.getSafeArea() + const tabBar = document.getElementsByTagName('ul')[0] + // 如果键盘高度低于高度的 1/3 且说 iOS 设备 + // PS:这种情况下是物理键盘输入模式,它不是个完整键盘 + // 这种情况下比较头疼,不能让 vebview 调整高度会出现黑色区域 + if(runtimeData.tags.platform == 'ios' && keyboardHeight < window.innerHeight / 3) { + // 修改 ResizeMode + Keyboard.setResizeMode({ mode: 'none' }) + // 这种情况下需要进行正常的底部避让,调整 --safe-area-bottom + const baseApp = document.getElementById('base-app') + if (safeArea && baseApp) { + baseApp.style.setProperty('--safe-area-bottom', (keyboardHeight - safeArea.bottom + 10) + 'px') + } + // 调整菜单高度 + if(safeArea && tabBar) { + tabBar.style.setProperty('padding-bottom', safeArea.bottom + 'px', 'important') + } + } else { + // 调整菜单高度 if(tabBar) { tabBar.style.setProperty('padding-bottom', '10px', 'important') } } + // 调整整个 HTML 的高度 // PS:仅用于解决 Android 在全屏沉浸式下键盘遮挡问题 const html = document.getElementsByTagName('html')[0] @@ -621,11 +643,22 @@ export async function loadMobile() { html.style.height = `calc(100% - ${keyboardHeight + safeArea.top}px)` } }) - Keyboard.addListener('keyboardWillHide', () => { + Keyboard.addListener('keyboardWillHide', async () => { + Keyboard.setResizeMode({ mode: 'native' }) + const baseApp = document.getElementById('base-app') + const safeArea = await runtimeData.plantform.pulgins.SafeArea?.getSafeArea() + if (safeArea && baseApp) { + baseApp.style.setProperty('--safe-area-bottom', safeArea.bottom + 'px') + } + const tabBar = document.getElementsByTagName('ul')[0] if(tabBar) { tabBar.style.paddingBottom = '' } + const sendMore = document.getElementById('send-more') + if(sendMore) { + sendMore.style.paddingBottom = 'var(--safe-area-bottom)' + } // 调整整个 HTML 的高度 // PS:仅用于解决 Android 在全屏沉浸式下键盘遮挡问题 const html = document.getElementsByTagName('html')[0] @@ -703,7 +736,7 @@ function showReleaseLog(data: any, isUpdated: boolean) { message: msg, updated: isUpdated, } - const buttonGoUpdate = runtimeData.tags.isElectron? [ + const buttonGoUpdate = (runtimeData.tags.isElectron || runtimeData.tags.isCapacitor) ? [ { text: $t('知道了'), fun: () => runtimeData.popBoxList.shift(), diff --git a/src/renderer/src/pages/Friends.vue b/src/renderer/src/pages/Friends.vue index 6eec9e6..ad5ef0a 100644 --- a/src/renderer/src/pages/Friends.vue +++ b/src/renderer/src/pages/Friends.vue @@ -180,16 +180,16 @@ -
-
+
+
{{ $t('选择联系人开始聊天') }}
+
+ + (っ≧ω≦)っ + {{ $t('别划了别划了被看见了啦') }} +
diff --git a/src/renderer/src/pages/Messages.vue b/src/renderer/src/pages/Messages.vue index 66c0932..4ff8aa2 100644 --- a/src/renderer/src/pages/Messages.vue +++ b/src/renderer/src/pages/Messages.vue @@ -112,16 +112,16 @@ @touchend="showMenuEnd" />
-
-
+
+
{{ $t('选择联系人开始聊天') }}
+
+ + (っ≧ω≦)っ + {{ $t('别划了别划了被看见了啦') }} +
From e7882701eb29f1d13ec576ffcad39ce6746ed1fc Mon Sep 17 00:00:00 2001 From: stapxs <1007028430.stapx@gmail.com> Date: Tue, 24 Dec 2024 10:05:57 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=B8=8A=E7=8F=AD=E4=B8=8D=E6=98=93?= =?UTF-8?q?=EF=BC=8C=E6=89=93=E7=9B=B9=E5=87=BA=E6=B0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit :wheelchair: Capacitor:优化在移动设备平板上横竖屏样式切换的体验 :bug: 修正空消息依旧触发消息预显的问题 <- #157 :bug: 修正 URL 编码遗漏导致的主题面板加载失败的问题 <- #158 :bug: 修正消息滚到底判定偶发不触发的问题 :bug: 阻止反复点击已打开的聊天以避免计数器问题 --- src/mobile/ios/App/App/Info.plist | 2 + src/renderer/src/App.vue | 5 +- .../append_mobile_horizontal.css} | 87 ------------------- .../append/mobile/append_mobile_vertical.css | 84 ++++++++++++++++++ src/renderer/src/function/option.ts | 9 +- src/renderer/src/function/utils/appUtil.ts | 51 ++++++++++- src/renderer/src/function/utils/msgUtil.ts | 4 + src/renderer/src/pages/Chat.vue | 2 +- src/renderer/src/pages/Messages.vue | 11 +-- src/renderer/src/pages/options/OptView.vue | 33 +------ 10 files changed, 156 insertions(+), 132 deletions(-) rename src/renderer/src/assets/css/append/{append_mobile.css => mobile/append_mobile_horizontal.css} (73%) create mode 100644 src/renderer/src/assets/css/append/mobile/append_mobile_vertical.css diff --git a/src/mobile/ios/App/App/Info.plist b/src/mobile/ios/App/App/Info.plist index 3817265..33e9987 100644 --- a/src/mobile/ios/App/App/Info.plist +++ b/src/mobile/ios/App/App/Info.plist @@ -36,6 +36,8 @@ UISupportedInterfaceOrientations~ipad + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight diff --git a/src/renderer/src/App.vue b/src/renderer/src/App.vue index 67dee05..de5a25b 100644 --- a/src/renderer/src/App.vue +++ b/src/renderer/src/App.vue @@ -212,6 +212,7 @@ +
@@ -226,13 +227,13 @@ import { Connector, login as loginInfo } from '@renderer/function/connect' import { Logger, popList, PopInfo, LogType } from '@renderer/function/base' import { runtimeData } from '@renderer/function/msg' import { BaseChatInfoElem } from '@renderer/function/elements/information' +import { Notify } from './function/notify' import * as App from './function/utils/appUtil' import Options from '@renderer/pages/Options.vue' import Friends from '@renderer/pages/Friends.vue' import Messages from '@renderer/pages/Messages.vue' import Chat from '@renderer/pages/Chat.vue' -import { Notify } from './function/notify' export default defineComponent({ name: 'App', @@ -240,7 +241,7 @@ export default defineComponent({ Options, Friends, Messages, - Chat, + Chat }, data() { return { diff --git a/src/renderer/src/assets/css/append/append_mobile.css b/src/renderer/src/assets/css/append/mobile/append_mobile_horizontal.css similarity index 73% rename from src/renderer/src/assets/css/append/append_mobile.css rename to src/renderer/src/assets/css/append/mobile/append_mobile_horizontal.css index f0f0fbe..db37531 100644 --- a/src/renderer/src/assets/css/append/append_mobile.css +++ b/src/renderer/src/assets/css/append/mobile/append_mobile_horizontal.css @@ -268,90 +268,3 @@ html { .friend-list > div:first-child { padding-top: var(--safe-area-top); } - -@media (max-width: 600px) { - .main-body > div { - height: calc(100% - 75px - var(--safe-area-top) - var(--safe-area-bottom)); - padding-bottom: calc(75px + var(--safe-area-bottom)); - margin-top: var(--safe-area-top); - } - - .opt-main-tab, - .main-body > div > div[name="主页"] { - margin-top: calc(1px - var(--safe-area-bottom))!important; - height: calc(100% + var(--safe-area-top) + var(--safe-area-bottom)) !important; - } - - .chat-pan { - box-shadow: 0 0 5px var(--color-shader); - } - - /* 联系人列表 */ - .friend-list .small { - display: none !important; - } - .friend-list .base { - display: flex !important; - } - .friend-list .base > span { - font-size: 1.5rem; - } - .friend-list .base > svg { - height: 1.3rem !important; - } - .friend-list > div:first-child { - padding-top: 0; - } - .friend-list > div:first-child label { - height: calc(1rem + 25px); - margin-top: 10px; - display: flex; - } - .friend-list > div:first-child label > input { - font-size: 1rem; - } - .friend-body > div:nth-child(1) { - transform: scaleY(0) !important; - height: unset !important; - width: 6px !important; - border-radius: 6px !important; - position: unset !important; - } - .friend-body > div:nth-child(1).new { - transform: scaleY(0.5) !important; - } - .exp-header:not(.open) { - display: flex !important; - } - - .chat-info > header { - margin-top: calc(var(--safe-area-top)); - flex-direction: row-reverse; - overflow: hidden; - transform: translateX(20px); - } - .chat-info>header>span { - font-size: 1.5rem; - font-weight: bold; - margin-bottom: 20px; - } - .chat-info>header>svg { - width: 2.2rem; - height: 2.2rem; - transform: translateX(calc(-50% + 0.5px)); - margin-right: -10px; - } - - .msg-img { - max-height: 20vh; - } - - .home-body { - width: 100%; - margin-left: 0; - } - - .opt-tab .tab-body > div { - padding: 0; - } -} diff --git a/src/renderer/src/assets/css/append/mobile/append_mobile_vertical.css b/src/renderer/src/assets/css/append/mobile/append_mobile_vertical.css new file mode 100644 index 0000000..e077463 --- /dev/null +++ b/src/renderer/src/assets/css/append/mobile/append_mobile_vertical.css @@ -0,0 +1,84 @@ +.main-body > div { + height: calc(100% - 75px - var(--safe-area-top) - var(--safe-area-bottom)); + padding-bottom: calc(75px + var(--safe-area-bottom)); + margin-top: var(--safe-area-top); +} + +.opt-main-tab, +.main-body > div > div[name="主页"] { + margin-top: calc(1px - var(--safe-area-bottom))!important; + height: calc(100% + var(--safe-area-top) + var(--safe-area-bottom)) !important; +} + +.chat-pan { + box-shadow: 0 0 5px var(--color-shader); +} + +/* 联系人列表 */ +.friend-list .small { + display: none !important; +} +.friend-list .base { + display: flex !important; +} +.friend-list .base > span { + font-size: 1.5rem; +} +.friend-list .base > svg { + height: 1.3rem !important; +} +.friend-list > div:first-child { + padding-top: 0; +} +.friend-list > div:first-child label { + height: calc(1rem + 25px); + margin-top: 10px; + display: flex; +} +.friend-list > div:first-child label > input { + font-size: 1rem; +} +.friend-body > div:nth-child(1) { + transform: scaleY(0) !important; + height: unset !important; + width: 6px !important; + border-radius: 6px !important; + position: unset !important; +} +.friend-body > div:nth-child(1).new { + transform: scaleY(0.5) !important; +} +.exp-header:not(.open) { + display: flex !important; +} + +.chat-info > header { + margin-top: calc(var(--safe-area-top)); + flex-direction: row-reverse; + overflow: hidden; + transform: translateX(20px); +} +.chat-info>header>span { + font-size: 1.5rem; + font-weight: bold; + margin-bottom: 20px; +} +.chat-info>header>svg { + width: 2.2rem; + height: 2.2rem; + transform: translateX(calc(-50% + 0.5px)); + margin-right: -10px; +} + +.msg-img { + max-height: 20vh; +} + +.home-body { + width: 100%; + margin-left: 0; +} + +.opt-tab .tab-body > div { + padding: 0; +} diff --git a/src/renderer/src/function/option.ts b/src/renderer/src/function/option.ts index 270b4c1..fc6e409 100644 --- a/src/renderer/src/function/option.ts +++ b/src/renderer/src/function/option.ts @@ -344,7 +344,7 @@ function loadOptData(data: { [key: string]: any }) { try { options[key] = JSON.parse(options[key]) } catch (e: unknown) { - // + // ignore } } else { options[key] = value @@ -395,15 +395,18 @@ export function get(name: string): any { } /** - * 从 cookie 中获取原始设置项值 + * 获取原始设置项值 * @param name 设置项名称 * @returns 设置项值(如果没有则为 null) + * @description 注意: + * 此方法获取原始设置项值,不会对值进行 T/F 转换、JSON 解析、URL 解码等操作; + * 在 Web 端和 Capacitor 端使用时由于存储在 WebStorage 中,需要特别注意预防上述未转换导致的错误。 */ export function getRaw(name: string) { if (runtimeData.plantform.reader) { return runtimeData.plantform.reader.sendSync('opt:get', name) } else { - // 解析拆分 cookie 并执行各个设置项的初始化方法 + // 解析拆分并执行各个设置项的初始化方法 const str = localStorage.getItem('options') if (str != null) { const list = str.split('&') diff --git a/src/renderer/src/function/utils/appUtil.ts b/src/renderer/src/function/utils/appUtil.ts index 30b1c22..7bf113d 100644 --- a/src/renderer/src/function/utils/appUtil.ts +++ b/src/renderer/src/function/utils/appUtil.ts @@ -448,6 +448,10 @@ export function createIpc() { } } + +import horizontalCss from '@renderer/assets/css/append/mobile/append_mobile_horizontal.css?raw' +import verticalCss from '@renderer/assets/css/append/mobile/append_mobile_vertical.css?raw' +// import windowsCss from '@renderer/assets/css/append/mobile/append_windows.css?raw' export async function loadAppendStyle() { const platform = runtimeData.tags.platform logger.info('正在装载补充样式……') @@ -461,12 +465,53 @@ export async function loadAppendStyle() { }) } - // 移动平台附加样式 + // 添加手机端样式 + const updateCss = (appendCss = '') => { + const cssStype = document.getElementById('mobile-css') + + const width = window.innerWidth + const height = window.innerHeight + if(width > 600 && cssStype) { + cssStype.innerHTML = (width > height ? horizontalCss : (horizontalCss +verticalCss)) + appendCss + } + + if(runtimeData.tags.isElectron) { + runtimeData.plantform.reader?.send('win:maximize') + const topBar = document.getElementsByClassName('top-bar')[0] as HTMLElement + if(topBar) { + topBar.style.display = 'none' + } + } + } if(runtimeData.tags.isCapacitor) { - import('@renderer/assets/css/append/append_mobile.css').then(() => { - logger.info('移动平台附加样式加载完成') + const styleTag = document.createElement('style') + styleTag.id = 'mobile-css' + document.head.appendChild(styleTag) + updateCss() + // 屏幕旋转事件处理 + window.addEventListener('resize', () => { + updateCss() }) } + // if((runtimeData.tags.isElectron && runtimeData.tags.platform == 'win32')) { + // runtimeData.plantform.reader?.invoke('sys:isTabletMode').then((isTabletMode: boolean) => { + // if(isTabletMode) { + // const styleTag = document.createElement('style') + // styleTag.id = 'mobile-css' + // document.head.appendChild(styleTag) + // updateCss(windowsCss) + // } + // }) + // // 屏幕旋转事件处理 + // window.addEventListener('resize', () => { + // runtimeData.plantform.reader?.invoke('sys:isTabletMode').then((isTabletMode: boolean) => { + // if(isTabletMode) { + // updateCss(windowsCss) + // } + // }) + // }) + // } + // UI 2.0 附加样式 if (runtimeData.tags.isElectron) { import('@renderer/assets/css/append/append_new.css').then(() => { diff --git a/src/renderer/src/function/utils/msgUtil.ts b/src/renderer/src/function/utils/msgUtil.ts index 79084a5..b64c67a 100644 --- a/src/renderer/src/function/utils/msgUtil.ts +++ b/src/renderer/src/function/utils/msgUtil.ts @@ -411,6 +411,10 @@ export function sendMsgRaw( msg: string | any[] | undefined, preShow = false, ) { + // 如果消息为空则不发送 + if(msg == undefined || msg == '' || (Array.isArray(msg) && msg.length == 0)) { + return + } // 将消息构建为完整消息体先显示出去 const msgUUID = uuid() if (preShow) { diff --git a/src/renderer/src/pages/Chat.vue b/src/renderer/src/pages/Chat.vue index 0eddb24..acbf166 100644 --- a/src/renderer/src/pages/Chat.vue +++ b/src/renderer/src/pages/Chat.vue @@ -1067,7 +1067,7 @@ this.loadMoreHistory() } // 底部 - if (body.scrollTop + body.clientHeight >= body.scrollHeight) { + if ((body.scrollTop + body.clientHeight + 10) >= body.scrollHeight) { this.NewMsgNum = 0 this.tags.showBottomButton = false // 去除阴影 diff --git a/src/renderer/src/pages/Messages.vue b/src/renderer/src/pages/Messages.vue index 4ff8aa2..9f3c3a1 100644 --- a/src/renderer/src/pages/Messages.vue +++ b/src/renderer/src/pages/Messages.vue @@ -182,7 +182,8 @@ * @param data 联系人对象 */ userClick(data: UserFriendElem & UserGroupElem) { - if (!this.trRead) { + const id = data.user_id ? data.user_id : data.group_id + if (!this.trRead && id != this.chat.show.id) { if (this.runtimeData.tags.openSideBar) { this.openLeftBar() } @@ -191,7 +192,7 @@ // 临时会话标志 temp: data.group_name == '' ? data.group_id : undefined, type: data.user_id ? 'user' : 'group', - id: data.user_id ? data.user_id : data.group_id, + id: id, name: data.group_name? data.group_name: data.remark === data.nickname? data.nickname: data.remark + '(' + data.nickname + ')', avatar: data.user_id? 'https://q1.qlogo.cn/g?b=qq&s=0&nk=' + data.user_id: 'https://p.qlogo.cn/gh/' + @@ -210,11 +211,11 @@ if ( runtimeData.sysConfig.chatview_name != '' && runtimeData.sysConfig.chatview_name != - getOpt('chatview_name') + decodeURIComponent(getOpt('chatview_name') ?? '') ) { runtimeData.sysConfig.chatview_name = - getOpt('chatview_name') - runOpt('chatview_name', getOpt('chatview_name')) + decodeURIComponent(getOpt('chatview_name') ?? '') + runOpt('chatview_name', decodeURIComponent(getOpt('chatview_name') ?? '')) } } // 清除新消息标记 diff --git a/src/renderer/src/pages/options/OptView.vue b/src/renderer/src/pages/options/OptView.vue index b20c299..d7baedb 100644 --- a/src/renderer/src/pages/options/OptView.vue +++ b/src/renderer/src/pages/options/OptView.vue @@ -122,28 +122,6 @@
-