Skip to content

githup v1.2.9(仓库页按返回一律先回代码 · 朴素样式底栏贴回屏幕底边)

Choose a tag to compare

@Buwrt Buwrt released this 26 Sep 03:57
· 582 commits to main since this release

这一版修的是一个真实现象:在仓库页的议题 / 拉取请求 / Actions / 发布 / 更多,
以及「更多」里进去的提交记录、分支、标签……上按返回,会去哪儿全看你是怎么进来的。

一、以前:返回键把走过的 tab 倒着走一遍

从「代码」连点「议题 → 拉取请求 → 发布」,想退出去得按三次返回:
先退到「拉取请求」,再退到「议题」,最后才回到「代码」。用户想要的其实是
「退出这一个 tab」,不是把刚才走过的路倒着回放一遍。

更难受的是另一条路:从搜索结果或者通知里直接点进某个仓库的「议题」——
历史里压根没有「代码」这一条,一按返回整个仓库页就没了。明明人还在仓库里,
却被弹回了搜索页。

根因就一句话:返回键走的是 history 逐级回退,而 tab 之间每次切换都往历史里堆一条。

来路 以前按返回
代码 → 议题 → 拉取请求 → 发布 退到「拉取请求」→「议题」→ 三次才回到代码
搜索结果 → 议题 历史里没有「代码」,直接退出仓库页
通知 → 发布 同上

二、顺带修掉:回到代码了,那一排 tab 却还停在右边

修完上面那条,现象变成「页面确实回到代码了,可那一排还停在后面」——
高亮是「代码」,可它在视野外,看着像没生效。

根因在位置记忆:返回走的是 replace,不是点击,于是渲染时走「按记忆原样恢复」
那条路,而记忆还停在右边(你上次为了够到「发布」拉过去的位置)。

现在 高亮落在「代码」时无条件把这一排拉回最左,并把记忆一起清掉 ——
不然下次回来又被拽到右边。「代码」是这一排的第一个,停在右边没有任何意义。

只认代码 tab:在「发布」「议题」上刷新,位置照旧不动(那是「刷新后位置不跑」,
另一条需求,不能一起改没)。

三、现在:一次返回到代码,再一次返回出仓库

两处一起改:

  • handleBack() 新增一步 —— 只要人在这个仓库、且不在代码 tab,返回就落到代码 tab;
    已经在代码 tab 了,才继续往上退(回搜索、回首页……)。这里用 replace 而不是 go:
    再 push 一条的话,历史会攒成「代码 → 议题 → 代码 → 议题」,按返回变成在这两页之间来回跳,
    永远退不出去。
  • pushRoute() 把「同一个仓库里换 tab」认定为横向切换,跟底部五个标签一样不堆历史。
    那一排 tab 是仓库页内部的并列视图,来回切不该留下痕迹。

于是历史栈里始终只有「进仓库前那一页 + 当前 tab」两条:
一次返回到代码,再一次返回出仓库。

四、该逐级退的地方,一步都不能跳

新规则只管 tab 层,下面是刻意不动的:

位置 按返回
tree / blob 文件浏览 它们本来就在代码 tab 里,照旧逐级退回仓库根
议题详情 / PR 详情 / 运行详情 / 提交详情 / Release 详情 先退回它自己那个 tab
搜索 / 通知 / 个人页 / 下载管理 与仓库无关,不受影响

判据是「这个路径是不是某个仓库的 tab 层」—— /owner/repo 后面最多只跟一个 tab 名,
带文件路径、议题号、commit sha、tag 的都不算。

五、同版追加:朴素样式下,底栏重新贴回屏幕底边

这一版发出之后又报来一个现象:关掉「iOS 风格」回到朴素那条实心底栏,
在有的机器上这一排没有贴着屏幕底边,和底之间留着一段空隙。

玻璃那一套从来没有这个问题。(版本号不变,直接重打包。)

为什么只有朴素样式看得出来。 底栏那一条是:

#tabbar { bottom: calc(var(--nav-lift) + var(--safe-b)); }

玻璃下 --nav-lift 是 14px —— 它是浮在半空的胶囊,任何误差都混在这 14px 的悬浮
感里,眼睛认不出来。朴素下它是 0:底栏到屏幕底边的距离就等于 --safe-b 这一个
数,原生量错多少,这里就空多少。同一个 bug,一半的人看不见。

而那个数是这么错的。

第一层是重复让位。MainActivity 只声明了 LAYOUT_FULLSCREEN,没有声明
LAYOUT_HIDE_NAVIGATION —— 也就是说系统已经替我们把导航栏那条留白留出来了,
WebView 本身的矩形根本就不含它。这时候前端再照着「导航栏有多高」让一次,
等于凭空多出一块。

第二层在 minSdk 上。它是 24,于是 Android 7~10 一律走这条分支 —— 直接读资源:

int idBot = r.getIdentifier("navigation_bar_height", "dimen", "android");
if (idBot > 0) bottom = r.getDimensionPixelSize(idBot);   // 恒为 48dp

那是 ROM 写死的上限值,跟「这台机器当下画没画导航栏」毫无关系:

机器 屏幕底部实际情况 资源里写的
Android 10 手势导航 只有一条细线 48dp
Android 9 三键导航 有一条 48dp(这条碰巧对了)
实体 Home / mBack 的老机型 根本没有软导航栏 48dp

同一份注释里还写着「手势导航下导航栏高度是很小的,不能写死 48dp」——
可那条约束只落实在 SDK ≥ 30 那一支,else 里照旧写死。「有的手机上」就是它们。

改法三处:

  1. 原生侧从「查配置」改成「量」。 拿 WebView 自己在屏幕坐标里的下沿去比屏幕
    真实底边(getLocationOnScreen vs getRealMetrics):

    • 够不到 → 系统已经留白了,页面自己不用再让,返回 0;
    • 够得到 → 页面确实铺到了屏幕底,这时只看系统条这会儿画没画出来,
      没画返回 0,画了才返回它真实高度;
    • 布局还没走完时不猜,同样返回 0 —— 宁可贴底,也不要让底栏飘在半空中。

    这套判据不依赖任何「照厂商配置估算」的量,ROM 怎么改都一样成立。

  2. CSS 把「底栏离屏幕底边」抽成 --nav-bottom 单独一条。 玻璃照旧用
    --safe-b,朴素钉死为 0 —— 朴素那一格的语义本来就是「贴着屏幕底边」,
    从此不再受原生那个数的影响。

  3. 前端加一道防御上限。 异常 ROM 报出几百 px 时截断到 min(32px, 屏高的 8%)。

顺带把 .fab、#toast-root、.sel-bar、#view 的 padding-bottom 一起改了 ——
它们都按「底栏上沿」定位,必须跟着同一个量走,否则就变成「底栏贴住了底、
内容却多空出一截」。

会不会被系统条压住?只有在「页面真的铺到屏幕最底 + 三键导航」时才可能,而这时
系统条是浮在页面之上的一层(导航栏已被设为透明),底栏主体仍然是完整的。
相比之下「离底一大截」是实实在在的错位,两者不在一个量级上。

代码自校验(不需要服务器)

包内自带两道:签名自校验(证书指纹不符直接拒绝运行)+ 源码指纹
(对源码文件算整体 SHA-256 并内嵌,被改过就报出来)。本次源码指纹(SRC_SHA256):

270b231eb90d63da48be74fa51c7f2f260d36a5a4d85fb441888a6d9e0d420fa

安装信息

项 值
文件名 githup-1.2.9.apk
大小 923,690 字节(约 902 KB)
SHA-256 69ba30e1cb5bad00a2fba9a834d7fc9cb3b6671dc63d3457b2702a88cdda456d
versionName / versionCode 1.2.9 / 1002009
应用名 / 包名 githup / com.hubmobile.app
最低系统 Android 7.0(API 24)

更新时才提醒,已是最新版完全静默。签名证书与之前一致,可直接覆盖安装,不用卸载。

更新时才提醒,已是最新版完全静默。签名证书与之前一致,可直接覆盖安装,不用卸载。