Telegram github commits and releases
4.53K subscribers
601 files
20.3K links
Broadcast from the most important Telegram clients' repositories
Download Telegram
morethanwords/tweb/masterda8b3807 files, +351/-345
Regenerate icons

#webk
🫡2
telegramdesktop/tdesktop/dev20542a13 files, +20/-14
Added logs of source path when an unknown deleted message is re-added.

Related commit: 384f6d9a31.

telegramdesktop/tdesktop/dev0cf37dd4 files, +28/-1
Replaced gift button with call button for channel owner in info top bar.

telegramdesktop/tdesktop/dev550f6231 files, +10/-1
Slightly improved trackpad scroll handling in profile flexible top bar.

telegramdesktop/tdesktop/dev16d97065 files, +111/-0
Added playback wave animation around voice message play button.

telegramdesktop/tdesktop/dev92e96441 files, +1/-2
Allowed swipe-to-reply gesture in channels.

telegramdesktop/tdesktop/dev9a38ab72 files, +4/-1
Fixed invisible small group call videos.

telegramdesktop/tdesktop/devc56fd451 files, +2/-2
Fixed repaint region for third column section animation.

telegramdesktop/tdesktop/dev969e84f1 files, +1/-0
Fixed clipped overlay buttons in group call QRhi viewport.

telegramdesktop/tdesktop/dev407d2cf4 files, +10/-0
Fixed new account intro opening in wrong window.

telegramdesktop/tdesktop/devdf64efd6 files, +37/-9
Fixed back from new account intro focusing wrong window.

telegramdesktop/tdesktop/dev5d52a286 files, +66/-2
Added experimental option to keep unmuted unread dialogs on top.

telegramdesktop/tdesktop/deva74ee608 files, +297/-0
Added initial support of swipe-next-channel.

telegramdesktop/tdesktop/dev49396c44 files, +565/-12
Added growing-capsule swipe-next-channel pull indicator with userpic.

#tdesktop
🫡3
telegramdesktop/tdesktop/dev75491857 files, +111/-14
Added bottom-up section slide for swipe-next-channel jump.

telegramdesktop/tdesktop/dev1b886122 files, +22/-10
Fixed stale truncated history view top bar title on peer name change.

telegramdesktop/tdesktop/dev792cc5c1 files, +18/-4
Fixed text recognition overlay rotation in QRhi media viewer.

telegramdesktop/tdesktop/dev2da46cb2 files, +52/-16
Added text recognition for image documents in media viewer.

telegramdesktop/tdesktop/devb9d6b079 files, +628/-17
Added recognized text selection and copying in overlay media viewer.

telegramdesktop/tdesktop/dev05cb1e43 files, +41/-4
Added blockquote and code block rendering to media viewer captions.

telegramdesktop/tdesktop/devd0dba2e7 files, +119/-23
Added text transfer between message field and gif caption box.

telegramdesktop/tdesktop/devd10e9ce8 files, +271/-17
Added alphabetical section headers to contacts list sorted by name.

telegramdesktop/tdesktop/dev076de2d6 files, +498/-0
Added alphabetical fast-scroll index strip to contacts box.

telegramdesktop/tdesktop/devb8e82e31 files, +8/-5
Fixed opening sections from the settings search results.

telegramdesktop/tdesktop/dev165d20a5 files, +106/-15
Added support of deep link copying to settings search results.

telegramdesktop/tdesktop/devc40446b2 files, +13/-4
[thanos] Fixed lost auto-scroll to bottom during animation.

telegramdesktop/tdesktop/dev0ef307f2 files, +29/-17
Added right-button clicks support to pinned bar.

#tdesktop
🫡4👍1
telegramdesktop/tdesktop/dev1ab85976 files, +106/-0
Added reverse iteration over pinned messages on right click.

telegramdesktop/tdesktop/deva1f3ee515 files, +193/-5
Added tooltip above link for hidden forwarded sender.

telegramdesktop/tdesktop/deve0504dd7 files, +763/-1121
[ai] Attempt to automate testing changes.

telegramdesktop/tdesktop/dev9ca694f1 files, +51/-51
Rename currency-balance and post-suggestion strings to Grams.

telegramdesktop/tdesktop/dev40896466 files, +41/-32
Refresh and unify the TON diamond vector icons.

telegramdesktop/tdesktop/devc9ed5ef1 files, +1/-1
Update lib_base.

telegramdesktop/tdesktop/devee39aa34 files, +4/-23
Switch to Qt's queued invoker

#tdesktop
🫡4
telegramdesktop/tdesktop/dev156c8e74 files, +21/-11
Use new base::option::changes in a few old options

telegramdesktop/tdesktop/dev1520a817 files, +7/-7
Bump actions/checkout from 6 to 7

Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
dependency-version: '7'
dependency-type: direct:production
update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

#tdesktop
🫡3💅1
telegramdesktop/tdesktop/dev1d178521 files, +1/-1
Return hinting for math formula fonts.

telegramdesktop/tdesktop/devc8ef31a4 files, +18/-26
Fix rich pages in scheduled / shorcuts sending.

telegramdesktop/tdesktop/dev54a7fd09 files, +101/-24
Use correct table entities limits.

telegramdesktop/tdesktop/devb01d3751 files, +1/-1
Add some more math formula guardrails.

telegramdesktop/tdesktop/devfa9b9265 files, +44/-48
Make InputField menu extension with hooks.

telegramdesktop/tdesktop/dev89977855 files, +81/-31
Enable jump-to-date in forum search.

telegramdesktop/tdesktop/dev2e54c331 files, +0/-2
Fix build with MSVC.

#tdesktop
🫡3
Ajaxy/telegram-tt/masterf45c51b3 files, +4/-4
12.0.30

Ajaxy/telegram-tt/mastercf4b7341 files, +2/-2
Chat Extra: Fix unofficial security risk block (#6977)

Ajaxy/telegram-tt/master0f2a87c1 files, +5/-2
Poll: Disable sending quiz with 1 option (#6980)

Ajaxy/telegram-tt/master7ddb46e3 files, +20/-1
Bot Forum: Change botoforum info button string (#6979)

Ajaxy/telegram-tt/master33ef4fb1 files, +14/-2
Chat List: Fix messege appearance after chat deletion (#6978)

Ajaxy/telegram-tt/master98e7644115 files, +1925/-5812
Migrate to Vite (#6973)

Ajaxy/telegram-tt/master6aa405f6 files, +1654/-156
[CI] Bundle Stats: Add Vite PR reporting (#6976)

Ajaxy/telegram-tt/masterf50eefa7 files, +4305/-6728
Tests: Migrate Jest suite to Vitest (#6981)

Ajaxy/telegram-tt/masterbac8e432 files, +73/-58
PR Stats: Change format (#6983)

Ajaxy/telegram-tt/masteraf5008b26 files, +544/-64
Reaction: Support reaction deletion (#6982)

Ajaxy/telegram-tt/master754be914 files, +90/-23
Vite: Show workers in stats (#7010)

Ajaxy/telegram-tt/master194f19960 files, +836/-745
Remove Buffer dependency (#7009)

Ajaxy/telegram-tt/master49f82ed1 files, +1/-0
Sync: Fix outdated global error (#7014)

Ajaxy/telegram-tt/master38e4b775 files, +15/-29
Safari: Fix several problems (#7015)

Ajaxy/telegram-tt/master9f01ca811 files, +210/-195
GifButton: Move to SCSS Modules (#7013)

#webz
🫡2
Ajaxy/telegram-tt/master48bf95b1 files, +30/-15
Forum: Load topics when listed ids are missing (#7016)

Ajaxy/telegram-tt/masterbee4c3a1 files, +2/-2
Left Main: Fix chat list with tabs layout (#7017)

Ajaxy/telegram-tt/master34474e76 files, +54/-8
Profile: Implement round corners in profile media (#7019)

Ajaxy/telegram-tt/masterf23a4ba3 files, +594/-597
Agents: Move CLAUDE.md to AGENTS.md (#7012)

Ajaxy/telegram-tt/masterd419be911 files, +31/-43
Sticker: Fix blinking on send (#7011)

Ajaxy/telegram-tt/master0b47bec2 files, +2/-2
Audio: Fix audio message transcribing button color (#7021)

Ajaxy/telegram-tt/masterb52deb13 files, +169/-12
Checklists: Fix emoji display for checklists in chat list (#7018)

Ajaxy/telegram-tt/master173280d4 files, +14/-6
Summary: Prevent hiding on error (#7023)

Ajaxy/telegram-tt/master764aaa42 files, +0/-508
Remove unused dependencies (#7024)

Ajaxy/telegram-tt/masterccd4bdc11 files, +0/-88
Remove unused functions (#7025)

Ajaxy/telegram-tt/master9c285e741 files, +156/-4438
Statistics: Upgrade to lovely-chart v2 npm package (#7027)

Ajaxy/telegram-tt/master54185fd7 files, +168/-139
Statistics: Restore lazy lovely-chart loading (#7028)

Ajaxy/telegram-tt/master954f0f1121 files, +7622/-759
Support Rich Messages & Instant View (#6963)

Ajaxy/telegram-tt/master0df85b84 files, +14/-13
Lang: Updates from platform (#7030)

#webz
🫡2
Ajaxy/telegram-tt/master68478f645 files, +615/-401
Redesign: Redesign Left panel and Middle header (#6971)

Co-authored-by: Alexander Zinchuk <alx.zinchuk@gmail.com>

Ajaxy/telegram-tt/mastere1f29881 files, +1/-1
Add .kml / .kmz as potentially IP-revealing. (#7031)

Ajaxy/telegram-tt/master73ff15010 files, +76/-63
Rich Messages: Small fixes (#7032)

Ajaxy/telegram-tt/master1fafd661 files, +2/-2
Reactor List Modal: Fix button hover (#7034)

Ajaxy/telegram-tt/master1ead0921 files, +2/-1
Topic: Fix error on min constructor (#7022)

Ajaxy/telegram-tt/masteree72f7110 files, +47/-33
Media Viewer: Fix ghost animation clipping (#7037)

Ajaxy/telegram-tt/master4cd5e768 files, +368/-6
Profile: Show long titles in line (#7020)

Ajaxy/telegram-tt/master3d85e9712 files, +96/-99
Middle Column: Support mask gradient (#7036)

Ajaxy/telegram-tt/master54f469327 files, +153/-74
Toncoin: Rebrand token to Gram

Rename the Toncoin token to "Gram" across user-facing strings and
localization keys, and add the new colored coin icon. The TON blockchain,
the `TON` currency code and protocol/API entities are left intact.

- Update display strings to use the name "Gram"
- Rename token localization keys (`*Ton*` -> `*Gram*`)
- Add `GramIcon` (colored SVG inline, PNG in Settings, `currentColor`
monochrome variant for amount-colored transactions)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Ajaxy/telegram-tt/master6f02c7f1 files, +2/-1
Rich Message: Fix more button hover color (#7038)

Ajaxy/telegram-tt/masterbada5e52 files, +20/-0
Modal: Fix Esc handling (#7043)

Ajaxy/telegram-tt/masterb9a888f18 files, +452/-493
Mini Apps: Fix theme color parsing (#7029)

Ajaxy/telegram-tt/masterb7764bc17 files, +51/-30
Search: Fix search input position in chat list (#7040)

#webz
🫡2
Ajaxy/telegram-tt/master5a78bb07 files, +275/-76
Calls: Migrate methods to object parameters (#7044)

Ajaxy/telegram-tt/master248690e1 files, +3/-0
Inline Bots: Support rich content (#7046)

Ajaxy/telegram-tt/master7b64d1b7 files, +15/-8
Styles: Redesign shadows (#7039)

Ajaxy/telegram-tt/master37480bc1 files, +1/-1
Folders: Disable left tab folders grey out in inactive state (#7041)

Ajaxy/telegram-tt/master7a618df2 files, +4/-2
Chat Invite Modal: Redesign (#7047)

Ajaxy/telegram-tt/master9602b8211 files, +96/-89
Revert "Middle Column: Support mask gradient (#7036)" (#7049)

Ajaxy/telegram-tt/master110eb871 files, +1/-1
Files: Fix progress spinner height init (#7052)

Ajaxy/telegram-tt/masterbcdf2a42 files, +1/-5
Contact Modal: Fix top margin for help text in New Contact Modal (#7053)

Ajaxy/telegram-tt/master84ee4479 files, +68/-6
Message: Show edited if needed (#7045)

Ajaxy/telegram-tt/master3f795db31 files, +934/-157
Management: Support guard bots (#7035)

Co-authored-by: Alexander Zinchuk <alx.zinchuk@gmail.com>

Ajaxy/telegram-tt/master0b401d41 files, +4/-0
Quick Preview Modal: Fix layout (#7054)

Ajaxy/telegram-tt/masterfc777e6300 files, +21565/-1530
[Build]

#webz
🫡2
morethanwords/tweb/master11fde946 files, +38/-13
Misc non-sticker fixes: folders sidebar notification badge, media spoiler cover, reactions no-select, CLAUDE.md note, langPack sync

- folders sidebar: reactive total notification count on the menu button (Accessor instead of cloning the toolbar count element)
- media: keep sensitive-content cover clickable during reveal so a repeat click is ignored instead of falling through
- reactions: disable text selection
- CLAUDE.md: add commit-policy note
- regenerate langPack.strings

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

#webk
🫡3
morethanwords/tweb/master550b4883 files, +195/-68
fix: format a shared contact's phone under the viewer's country, not a misread foreign code

Bug (bugs.telegram.org #30681): a phone number in an in-chat shared contact
embed is displayed with the wrong country code when the stored vCard number does
not explicitly contain its dialing prefix. The leading national/city digits are
shown as if they were the country code (does not happen on Android).

Root cause: formatPhoneNumber (src/helpers/formatPhoneNumber.ts) strips every
non-digit and then ALWAYS resolves a country by greedily matching the longest
numeric prefix against every known country code. For a number stored without its
dialing prefix (e.g. an Indonesian national mobile "8123456789"), the leading
"81" collide with Japan (+81): "81" is stripped as the country code and the rest
is regrouped under it, so "8123456789" rendered as "+81 23 4567 89" in the
contact bubble (src/components/chat/bubbles.ts, messageMediaContact). Registered
users (user.phone) always carry their country code, so this only surfaces for the
arbitrary vCard phone_number of a shared contact.

Fix: mirror Android's PhoneFormat, which biases an unprefixed number to the
viewer's own country instead of guessing one from the leading digits.

- formatPhoneNumber takes an opt-in `defaultCountryCode` (the viewer's own
calling code). When the input has no explicit '+' AND its digits do not already
start with that code, the number is treated as a national number of the
viewer's country and grouped with that country's national patterns; `code` is
returned undefined so the caller omits the '+'. Otherwise (explicit '+', or
digits already starting with the viewer's code) the existing greedy detection
runs unchanged, so a registered user's fully-qualified phone and an
international "+..." contact keep their grouping. The grouping logic is factored
into a shared applyPattern() helper.
- bubbles.ts reads the viewer's country code once from the warm main-thread user
cache (apiManagerProxy.getUser(rootScope.myId)) — synchronous, no chat-open
round-trip — and prefixes '+' only when a country code is present. Every other
formatPhoneNumber caller (profile, search, payments, telInputField) is
unchanged.

Result: a same-country contact regains correct grouping (e.g. "+7 999 123-45-67"),
the #30681 number is grouped under the viewer's country with no false foreign code
(Indonesian "8123456789" -> "812 3456789", never "+81 ..."), and a number that
does carry its own code still renders "+CC ...".

Test (src/tests/formatPhoneNumber.test.ts): pure-unit Vitest with two countries
whose leading digits overlap (JP +81, ID +62). Asserts the #30681 input is
grouped under the viewer (+62) with code undefined and never attributed to Japan;
plus the own-country international "+CC", explicit-'+' detection, the
foreign-under-viewer no-"+CC" case, and the unchanged default parse. 6/6 green
(one reproduces the bug before the fix).

Gates: tsc --noEmit 0 errors; eslint 0 on all changed files; vitest 6/6 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

#webk
🫡3
telegramdesktop/tdesktop/devef76b586 files, +45/-29
Fix reaction preview crash in stories.

telegramdesktop/tdesktop/dev2622f025 files, +487/-98
Improve context of messages copied to clipboard.

#tdesktop
🫡3
telegramdesktop/tdesktop/dev9f61a9f2 files, +4/-2
Work around freeze on Windows on ARM.

Fixes #30867.

#tdesktop
🫡3
telegramdesktop/tdesktop/nightly548185f2 files, +19/-17
Moved out IsDarkTaskbar() from the Windows tray module.

telegramdesktop/tdesktop/nightly14efa2d7 files, +342/-5
Added playback controls to Windows taskbar thumbnail.

#tdesktop
🫡3
telegramdesktop/tdesktop/dev5ba77ac2 files, +125/-21
[img-editor] Added pinch zoom gesture support.

telegramdesktop/tdesktop/devc9c02ad4 files, +36/-29
[poll-view] Fixed description being selected instead of question.

telegramdesktop/tdesktop/devc02a3581 files, +1/-1
Fixed wrong caption being selected in file albums.

telegramdesktop/tdesktop/deve37fc1d2 files, +42/-0
Added pinch zoom gesture support to media viewer.

telegramdesktop/tdesktop/dev6ab3a8e4 files, +69/-5
Added swipe left-right navigation gesture to media viewer.

telegramdesktop/tdesktop/dev1a0b5041 files, +3/-1
Added billions suffix to shortened counters.

telegramdesktop/tdesktop/devb023fd22 files, +11/-2
Limited contacts alphabetical section headers to contacts box.

telegramdesktop/tdesktop/deva2f2db33 files, +6/-2
Made discussion group open in same non-primary window as its channel.

telegramdesktop/tdesktop/dev57fdc4b2 files, +5/-1
Fixed macOS now playing timeline drift after pausing playback.

telegramdesktop/tdesktop/dev858a8fd2 files, +23/-1
Reflected the playback speed in macOS now playing timeline.

telegramdesktop/tdesktop/dev3adc0c12 files, +20/-1
Mapped macOS now playing skip buttons to relative seeking.

telegramdesktop/tdesktop/devb7dff422 files, +45/-14
[ai] Localize testing attempts.

telegramdesktop/tdesktop/dev4e6295b1 files, +154/-94
[ai] Bring Codex skill up to speed.

telegramdesktop/tdesktop/dev0782b4d2 files, +71/-19
[ai] Default to .ai/{project}/tasks/about.md task.

#tdesktop
🫡3
telegramdesktop/tdesktop/dev24280692 files, +26/-14
[ai] Clean up implementing.md every run.

#tdesktop
🫡2
telegramdesktop/tdesktop/dev18df9412 files, +109/-1
Added screen reader tab-control accessibility for chat folders.

telegramdesktop/tdesktop/dev7ffb2c51 files, +4/-0
Report the chat-folders tab strip as a vertical tab control

Override TabListLayout::accessibilityOrientation() to return
Qt::Vertical, so screen readers announce the folders strip as a vertical
tab control (UIA Orientation). Relies on desktop-app/lib_ui#304 and
desktop-app/patches#254.

telegramdesktop/tdesktop/devc48860d1 files, +4/-0
Expose locked folders as plain buttons, not selectable tabs

A locked (premium) folder can never become the current tab - pressing it
opens the Premium box. Mark it not a page tab once locked, so it reports
as a plain button instead of a selectable PageTab and the tab container's
select() correctly rejects it.

telegramdesktop/tdesktop/dev9a5ec8b3 files, +12/-1
Fixed stuck voice waveform highlight after leaving hovered message.

telegramdesktop/tdesktop/dev8b4ccb71 files, +4/-0
Added display of hovered waveform time to voice message status line.

telegramdesktop/tdesktop/dev91fb1682 files, +19/-17
Moved out IsDarkTaskbar() from the Windows tray module.

telegramdesktop/tdesktop/dev6477fdd6 files, +337/-5
Added playback controls to Windows taskbar thumbnail.

Fixed #30402.

telegramdesktop/tdesktop/dev1c6220a1 files, +1/-1
Update lib_ui submodule.

#tdesktop
🫡2
telegramdesktop/tdesktop/deve99928b2 files, +25/-9
Added custom emoji size support to sticker uploading.

telegramdesktop/tdesktop/dev6241d233 files, +137/-40
Added custom emoji creation flow to sticker creator box.

telegramdesktop/tdesktop/dev103c2567 files, +157/-51
Added new-emoji button with menu to emoji set boxes.

telegramdesktop/tdesktop/dev9895e5b4 files, +128/-0
Added adapting existing sticker into custom emoji.

telegramdesktop/tdesktop/devff2dfbf5 files, +65/-21
Improve accessibility changes for left filters.

telegramdesktop/tdesktop/deve4cde251 files, +1/-1
Fix build with Qt 5.

#tdesktop
🫡2
morethanwords/tweb/master154f42d2 files, +60/-1
fix: stringMiddleOverflow no longer exceeds maxLength (output was always ~maxLength+3)

Bug
---
`stringMiddleOverflow(str, maxLength)` is a middle-ellipsis truncation helper
used to shorten a string to fit a budget (e.g. the empty-search hint shortens
the query to 18 chars in topbarSearch.tsx). But its output was systematically
LONGER than the requested maxLength — and for inputs only slightly over the
limit it was even longer than the original string, defeating the helper's
entire purpose. This is the same class of off-by-the-ellipsis defect already
fixed elsewhere in the formatter cluster.

Same symptom as the platform reports about truncated/oversized inline labels;
discovered via a discovery scan over src/helpers/string during the Forge bug
lane (the well-mined number/byte/duration formatters were skipped per journal).

Root cause (current code)
-------------------------
str.slice(0, maxLength / 2 | 0) + '...' + str.slice(-Math.round(maxLength / 2))

The two halves already sum to ~maxLength, then a 3-char ellipsis is added ON
TOP, so the result length is always ≈ maxLength + 3. The 3-char ellipsis budget
was never subtracted. Examples (before):
stringMiddleOverflow('abcdefgh', 6) -> 'abc...fgh' (9 chars, > 6 AND > input 8)
stringMiddleOverflow('a'.repeat(20),18)-> 21 chars (> 18 AND > input 20)

Fix
---
Reserve the ellipsis length from the budget before splitting head/tail — the
same idiom the sibling helpers fitSymbols / limitSymbols already use:

const budget = Math.max(0, maxLength - ellipsis.length);
head = ceil(budget/2), tail = floor(budget/2)

Output is now always ≤ maxLength; the head+ellipsis+tail shape and the
"return unchanged when it already fits" fast path are preserved.

Test evidence (src/tests/stringMiddleOverflow.test.ts)
------------------------------------------------------
4 tests. BEFORE the fix 2 fail:
"never exceeds maxLength for any overflowing input"
-> AssertionError: expected 9 to be less than or equal to 6
"shortened result is never longer than the original (maxLength 18)"
-> AssertionError: expected 21 to be less than or equal to 18
AFTER the fix all 4 pass (the unchanged-fit + head/ellipsis/tail-shape tests
also lock the preserved behavior).

Gates: tsc --noEmit 0 errors · eslint 0 · vitest 4/4 green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 8ab148fed4cfa6d0d8a3ad9e835b9aa6b0b0d3e7)

#webk
🫡3
morethanwords/tweb/masteraa433ff2 files, +51/-1
fix: getWeekNumber divided a ms delta by a seconds constant (1000x off)

Bug (forge discovery scan over src/helpers/date.ts)
getWeekNumber computed the ISO week number as

Math.ceil((((d.getTime() - yearStart.getTime()) / ONE_DAY) + 1) / 7)

but getTime() deltas are in milliseconds while ONE_DAY is 86400 (seconds).
Dividing a millisecond span by the seconds-per-day constant inflates the
day count ~1000x, so the function returned absurd values: getWeekNumber for
2024-06-21 yielded 24429 instead of the ISO week 25; for 2017-01-02 it
returned 572 instead of 1. The algorithm is copied verbatim from
https://stackoverflow.com/a/6117889, which divides by 86400000 (ms/day) —
the port dropped the *1000.

Reachability
getWeekNumber is exported. Its single in-app caller (formatDateAccordingTo
TodayNew, "current week" weekday-format branch) compares two dates already
within ~7 days, and the 1000x scaling cancels out under that equality
comparison — so today's user-visible behavior is unchanged (verified
exhaustively: 0 branch-decision differences across 2018–2031, every day,
hourly within the 7-day gate). The fix therefore hardens an exported helper
that returns a grossly wrong number for any other/future caller, with no
behavior change to the existing one. Strictly more correct.

Fix
Divide by ms-per-day (ONE_DAY * 1000). 1-line change + clarifying comment.

Evidence
New src/tests/getWeekNumber.test.ts: 7 cases vs ISO-8601 reference week
numbers (incl. Sunday→prev-year week 52, year-end roll into next ISO year,
and a 1..53 range sweep over a full year). Before: 6/7 FAIL
(e.g. "expected 858 to be 1", "expected 51715 to be <= 53"). After: 7/7 pass.

Gates: tsc 0 · eslint 0 (date.ts + test) · vitest 7/7.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 0ef09e626c661017807104466789b27886568ba1)

morethanwords/tweb/master15221e22 files, +38/-1
fix: correct alpha compositing in rgbaToRgb (background coefficient)

Bug (discovery scan, src/helpers/color.ts — pure helper)
rgbaToRgb() flattens an RGBA colour over an OPAQUE background. The
correct compositing formula is out = a*fg + (1 - a)*bg, but the code
weighted the background term by `a` as well:

a * (color/255) + (a * (bg/255)) // both terms scaled by a

Root cause (current source, color.ts:294)
The background contribution used `a` instead of `(1 - a)`. Consequences:
- a = 1 (opaque fg) returns fg + bg (clamped), not fg.
- a = 0 (transparent fg) returns 0, not bg.
- it only happens to be correct at a == 0.5 (where a == 1 - a), which
hid the bug for the common case.

Impact
webApp.tsx setHeaderColor() calls rgbaToRgb([...textColor, textOpacity],
headerRgb) to derive the Mini App header's --secondary-text-color by
flattening semi-transparent secondary text over the header background.
textOpacity comes from calculateOpacity() and ranges 0.5..0.64, so any
opacity above 0.5 produced a wrong (too-bright/over-saturated) colour.

Fix
Weight the background term by (1 - a). One-line change; output unchanged
for a == 0.5 and strictly correct elsewhere.

Tests (src/tests/colorRgbaToRgb.test.ts, new)
5 cases vs an alpha-compositing reference: opaque-fg, transparent-fg,
0.5 midpoint, the non-0.5 webApp.tsx usage, and a no-overflow check.
Before: 3 failed (opaque/transparent/non-0.5), 2 passed (0.5 cases).
After: 5/5 pass.

Gates: tsc 0 · eslint 0 (both files) · vitest 5/5.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

#webk
🫡3