dsh-mobile-flow 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/README.zh.md +2 -1
- package/lib/client.js +70 -24
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,7 +17,8 @@ On viewports ≤720px (the same breakpoint the official question card uses):
|
|
|
17
17
|
1. **The composer seat joins the document flow** — input bar and confirmation cards now live at the end of the transcript. Swipe up and they scroll out of view; the transcript becomes full-screen.
|
|
18
18
|
2. **Short conversations still dock to the bottom** — when the transcript is shorter than one screen, the message area stretches so the composer stays flush with the viewport floor, visually identical to the stock behavior. Long conversations get the full-screen treatment.
|
|
19
19
|
3. **Floating controls re-anchor** — the back-to-bottom button and turn navigator no longer reserve height for the sticky seat and sit close to the viewport floor again.
|
|
20
|
-
4. **
|
|
20
|
+
4. **Slim edges** — the content-layer paddings that keep the transcript, header, input card, and confirmation cards well off the screen edges (16–32px per side) shrink to a slim 4px side inset (8px top), reclaiming most of the wasted width without the cramped feel of full-bleed. The page shell itself never adds whitespace; the gaps come entirely from these paddings.
|
|
21
|
+
5. **No auto-focus on session switch** — the stock UI returns focus to the input box on every mount / session switch (a desktop convenience), which pops the on-screen keyboard over half the screen on phones. In narrow viewports the programmatic focus is swallowed; tapping the input box still focuses it normally.
|
|
21
22
|
|
|
22
23
|
Desktop (wide viewports) is completely unaffected.
|
|
23
24
|
|
package/README.zh.md
CHANGED
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
1. **composer 座位回归文档流** —— 输入框和确认卡片位于消息流末尾。上滑时随内容滚出视口,消息全屏可读。
|
|
18
18
|
2. **短会话仍然贴底** —— 消息不足一屏时消息区自动拉伸,输入框保持贴视口底,视觉与官方行为完全一致;长会话则享受全屏阅读。
|
|
19
19
|
3. **浮动控件重新锚定** —— 回到底部按钮、轮次导航不再为吸底座位预留高度,回到贴近视口底的位置。
|
|
20
|
-
4.
|
|
20
|
+
4. **纤细边距** —— 消息区、会话头部、输入卡、确认卡片与屏幕边缘之间的内容层 padding(每边 16–32px)收窄为左右 4px、顶部 8px 的纤细边距,收复大部分被浪费的宽度,又不像完全贴边那样局促。页面外壳本身不产生空白,间隙完全来自这些 padding。
|
|
21
|
+
5. **切会话不自动聚焦** —— 官方在每次挂载/切换会话时把焦点还给输入框(桌面便利设计),手机上会弹出输入法占掉半屏。窄屏时拦截这类程序化聚焦;你主动点输入框时照常聚焦。
|
|
21
22
|
|
|
22
23
|
桌面端(宽视口)完全不受影响。
|
|
23
24
|
|
package/lib/client.js
CHANGED
|
@@ -45,38 +45,30 @@ window.__ModuleLoader__.load({
|
|
|
45
45
|
" [data-conversation-scroll]:not(:has([data-conversation-composer-overlay])) {",
|
|
46
46
|
" --dsh-composer-height: 0px !important;",
|
|
47
47
|
" }",
|
|
48
|
-
" /* 4)
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
" /* a) Shared side-clearance variable ->
|
|
53
|
-
" question-card frame reference it via calc()
|
|
54
|
-
" their side insets and the composer width axis in one place. */",
|
|
48
|
+
" /* 4) Slim edges: the stock content-layer paddings (16-32px per side)",
|
|
49
|
+
" waste too much of a narrow screen, while full-bleed zero feels",
|
|
50
|
+
" cramped — keep a slim 4px side inset (8px top) instead. The page",
|
|
51
|
+
" shell itself never adds whitespace; only these paddings matter. */",
|
|
52
|
+
" /* a) Shared side-clearance variable -> 4px: the input card root and",
|
|
53
|
+
" the question-card frame reference it via calc(). */",
|
|
55
54
|
" [data-phase] {",
|
|
56
|
-
" --dsh-composer-side-clearance:
|
|
55
|
+
" --dsh-composer-side-clearance: 4px !important;",
|
|
57
56
|
" }",
|
|
58
|
-
" /* b) Transcript scroller (CSS-Modules _scroll class):
|
|
59
|
-
"
|
|
60
|
-
"
|
|
57
|
+
" /* b) Transcript scroller (CSS-Modules _scroll class): 32px sides and",
|
|
58
|
+
" 16px top -> 4px sides / 8px top (the variable above only removes",
|
|
59
|
+
" part of the side value; the fixed rest needs a direct hit). */",
|
|
61
60
|
" [data-conversation-scroll] [class*='_scroll'] {",
|
|
62
|
-
" padding:
|
|
61
|
+
" padding: 8px 4px !important;",
|
|
63
62
|
" }",
|
|
64
63
|
" /* c) Session header (the _header element inside the session.header",
|
|
65
|
-
" slot container): 12px top + 28/20px sides ->
|
|
66
|
-
" flush with the screen edges. */",
|
|
64
|
+
" slot container): 12px top + 28/20px sides -> 8px top / 6px sides. */",
|
|
67
65
|
" [data-slot='conversation.session.header'] > [class*='_header'] {",
|
|
68
|
-
" padding: 0 !important;",
|
|
66
|
+
" padding: 8px 6px 0 !important;",
|
|
69
67
|
" }",
|
|
70
|
-
" /* d)
|
|
71
|
-
"
|
|
72
|
-
" zero vertical padding already, so this is a no-op there). */",
|
|
73
|
-
" [data-composer-seat] [class*='_root'] {",
|
|
74
|
-
" padding-bottom: 0 !important;",
|
|
75
|
-
" }",
|
|
76
|
-
" /* e) Question/approval card frame (_frame): 6px top / 10px bottom",
|
|
77
|
-
" plus the side calc -> 0, confirmation cards sit flush too. */",
|
|
68
|
+
" /* d) Question/approval card frame (_frame): stock side calc",
|
|
69
|
+
" (clearance + 16px) -> 4px; vertical rhythm kept as stock. */",
|
|
78
70
|
" [data-composer-seat] [class*='_frame'] {",
|
|
79
|
-
" padding:
|
|
71
|
+
" padding: 6px 4px 10px !important;",
|
|
80
72
|
" }",
|
|
81
73
|
"}",
|
|
82
74
|
].join("\n");
|
|
@@ -92,6 +84,60 @@ window.__ModuleLoader__.load({
|
|
|
92
84
|
tag.remove();
|
|
93
85
|
};
|
|
94
86
|
});
|
|
87
|
+
|
|
88
|
+
ctx.effect(function () {
|
|
89
|
+
return installNoAutoFocus();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/* 5) No auto-focus on session switch (narrow viewports): InputBar's
|
|
94
|
+
unlock effect focuses the contenteditable on every mount / session
|
|
95
|
+
switch (packages/client/ui-conversation/.../InputBar.tsx, deps
|
|
96
|
+
[locked, sessionId, editor]) — a desktop convenience that pops the
|
|
97
|
+
IME over half the screen on phones. Swallow programmatic focus() on
|
|
98
|
+
the composer's editable unless the user just tapped it (or is
|
|
99
|
+
keyboard-navigating); taps reach the box via the normal focus path.
|
|
100
|
+
Question-card textareas (autoFocus on purpose) are not contenteditable
|
|
101
|
+
and stay untouched. */
|
|
102
|
+
function installNoAutoFocus() {
|
|
103
|
+
if (typeof window.matchMedia !== "function") return function () {};
|
|
104
|
+
var narrow = window.matchMedia("(max-width: 720px)");
|
|
105
|
+
var lastPointer = { target: null, time: 0 };
|
|
106
|
+
var lastKey = 0;
|
|
107
|
+
var onPointerDown = function (e) {
|
|
108
|
+
lastPointer.target = e.target;
|
|
109
|
+
lastPointer.time = Date.now();
|
|
110
|
+
};
|
|
111
|
+
var onKeyDown = function () { lastKey = Date.now(); };
|
|
112
|
+
document.addEventListener("pointerdown", onPointerDown, true);
|
|
113
|
+
document.addEventListener("keydown", onKeyDown, true);
|
|
114
|
+
|
|
115
|
+
function userInitiated(el) {
|
|
116
|
+
var now = Date.now();
|
|
117
|
+
if (now - lastKey < 500) return true;
|
|
118
|
+
if (now - lastPointer.time > 600) return false;
|
|
119
|
+
var t = lastPointer.target;
|
|
120
|
+
return t !== null && (t === el || (typeof t.contains === "function" && t.contains(el)));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
var nativeFocus = HTMLElement.prototype.focus;
|
|
124
|
+
HTMLElement.prototype.focus = function (opts) {
|
|
125
|
+
if (
|
|
126
|
+
narrow.matches &&
|
|
127
|
+
this.isContentEditable === true &&
|
|
128
|
+
typeof this.closest === "function" &&
|
|
129
|
+
this.closest("[data-composer-seat]") !== null &&
|
|
130
|
+
!userInitiated(this)
|
|
131
|
+
) {
|
|
132
|
+
return; /* swallow programmatic focus on the composer */
|
|
133
|
+
}
|
|
134
|
+
return nativeFocus.call(this, opts);
|
|
135
|
+
};
|
|
136
|
+
return function () {
|
|
137
|
+
HTMLElement.prototype.focus = nativeFocus;
|
|
138
|
+
document.removeEventListener("pointerdown", onPointerDown, true);
|
|
139
|
+
document.removeEventListener("keydown", onKeyDown, true);
|
|
140
|
+
};
|
|
95
141
|
}
|
|
96
142
|
|
|
97
143
|
exports.apply = apply;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-mobile-flow",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Mobile in-flow composer for the DeepSeek Harness Web UI: on narrow (≤720px) screens the input bar and AI confirmation cards scroll with the page instead of pinning to the viewport floor
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Mobile in-flow composer for the DeepSeek Harness Web UI: on narrow (≤720px) screens the input bar and AI confirmation cards scroll with the page instead of pinning to the viewport floor, edges slim down, and session switches no longer auto-focus the input. Client-side CSS overlay plus a narrow-only focus guard.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "lib/index.js",
|