Skip to content

sync: dev to extern-contrib#950

Merged
boomzero merged 24 commits intoextern-contribfrom
dev
Mar 15, 2026
Merged

sync: dev to extern-contrib#950
boomzero merged 24 commits intoextern-contribfrom
dev

Conversation

@github-actions
Copy link
Contributor

@github-actions github-actions bot commented Mar 15, 2026

sync-branches: New code has just landed in dev, so let's bring extern-contrib up to speed!


Summary by cubic

Add messages.html, a standalone WebUI for XMOJ short messages so iOS/iPadOS and other browsers without userscript support can read and send messages. Updated index.html with a nav link and switched bootstrap CDN to cdnjs for better accessibility.

  • New Features

    • Session (PHPSESSID) login with simple per-browser instructions; optional desktop bookmarklet.
    • Thread view with Markdown rendering via marked sanitized by dompurify, plus image upload from clipboard or file.
    • User info modal and badges, local contact search, auto-refresh, and a light/dark/auto theme toggle.
  • Bug Fixes

    • Include required DebugMode in API requests to prevent failures.
    • Sort messages oldest-first with auto-scroll to the latest; highlight incoming unread rows only.
    • Fix dark-mode styles for table-primary and improve link/image behavior (open in new tab, click to zoom).

Written for commit 3ea071d. Summary will update on new commits.

boomzero and others added 24 commits March 15, 2026 16:25
Adds a standalone messages.html page hosted on the Cloudflare Pages site,
allowing iOS/iPadOS users (and anyone without userscript support) to read
and send XMOJ short messages via the existing API.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…bility

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… instructions

Bookmarklets are not usable on mobile and confusing on desktop.
Make the session (PHPSESSID) tab the default with an accordion of
step-by-step instructions for Chrome, Firefox, Safari (macOS), and
iOS/iPadOS. Bookmarklet tab kept as secondary option for desktop users.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
API returns "参数DebugMode未找到" without it, causing all calls to fail.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Status badge (未读/已读) now reflects IsRead directly.
Row highlight (table-primary) still only applies to incoming unread messages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Desktop/mobile login tab priority: bookmarklet on desktop (pointer: fine), session on mobile
- Replace sender name links with Bootstrap popovers showing user info popup
- Image zoom: cursor: zoom-in/zoom-out, title tooltip on images
- Global Ctrl+V paste handler for images anywhere in thread view
- Auto-resize compose textarea as user types

Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
…nfo modal

Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
…in userinfo fetch

Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
…ck + auto-scroll fix

Co-authored-by: PythonSmall-Q <106425289+PythonSmall-Q@users.noreply.github.com>
feat(messages.html): user badges, contact search, auto-scroll to latest
Add caption "点击任意行打开对话 →" above table and a › chevron
in a trailing column on each row.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Restored: contact search, renderMailList, mailListCache, user badges,
user info modal, userSpan, auto-resize textarea, global paste handler,
requestAnimationFrame scroll, setLoginTab, dark-mode table-primary fix.

Added on top: caption "点击任意行打开对话 →" and › chevron column
to make list rows obviously clickable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Shan Wenxiao <seanoj_noreply@yeah.net>
Signed-off-by: Shan Wenxiao <seanoj_noreply@yeah.net>
feat: messages.html WebUI for short messages
@cloudflare-workers-and-pages
Copy link

Deploying xmoj-script-dev-channel with  Cloudflare Pages  Cloudflare Pages

Latest commit: 3ea071d
Status: ✅  Deploy successful!
Preview URL: https://0af58099.xmoj-script-dev-channel.pages.dev

View logs

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.2.3/js/bootstrap.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.2.3/js/bootstrap.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
</div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.

<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/js/bootstrap.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.6/purify.min.js"></script>

Check warning

Code scanning / CodeQL

Inclusion of functionality from an untrusted source Medium

Script loaded from content delivery network with no integrity check.
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="messages.html">

<violation number="1" location="messages.html:916">
P2: Decoding the combined `username:session` string before splitting on `:` breaks parsing when the username contains a colon. Split on the first `:` of the raw (still-encoded) string, then `decodeURIComponent` each part separately.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

function checkSessionHash() {
var hash = location.hash;
if (!hash.startsWith('#session=')) return false;
var val = decodeURIComponent(hash.slice('#session='.length));
Copy link

@cubic-dev-ai cubic-dev-ai bot Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Decoding the combined username:session string before splitting on : breaks parsing when the username contains a colon. Split on the first : of the raw (still-encoded) string, then decodeURIComponent each part separately.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At messages.html, line 916:

<comment>Decoding the combined `username:session` string before splitting on `:` breaks parsing when the username contains a colon. Split on the first `:` of the raw (still-encoded) string, then `decodeURIComponent` each part separately.</comment>

<file context>
@@ -0,0 +1,1061 @@
+function checkSessionHash() {
+    var hash = location.hash;
+    if (!hash.startsWith('#session=')) return false;
+    var val = decodeURIComponent(hash.slice('#session='.length));
+    var idx = val.indexOf(':');
+    if (idx < 1) return false;
</file context>
Fix with Cubic

@boomzero boomzero enabled auto-merge March 15, 2026 11:59
@boomzero boomzero merged commit 97e906e into extern-contrib Mar 15, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants