Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
216 commits
Select commit Hold shift + click to select a range
c6fc886
feat(video): add swipe pager below player
pgs666 Jun 1, 2026
d53015b
fix(video): restore pager drag tracking
pgs666 Jun 1, 2026
fd2da45
fix(video): ignore pager drag in horizontal sections
pgs666 Jun 1, 2026
fa01866
fix(video): prevent card navigation after drag
pgs666 Jun 1, 2026
ad37c31
fix(video): keep card scrolling responsive
pgs666 Jun 1, 2026
cd86f1d
fix(player): prevent swipe volume HUD from sticking
pgs666 Jun 1, 2026
0e475c0
fix(player): reset swipe HUD on gesture cancellation
pgs666 Jun 1, 2026
15392cb
fix(player): debounce physical volume HUD events
pgs666 Jun 1, 2026
ef09a44
fix(video): preserve player collapse across tab switches
pgs666 Jun 1, 2026
e63e9fa
fix(video): smooth shared player collapse across tabs
pgs666 Jun 1, 2026
b0f33b4
refactor(video): isolate player collapse state model
pgs666 Jun 1, 2026
5a8c0e0
fix(video): stabilize pager viewport during player collapse
pgs666 Jun 1, 2026
b1c1e70
fix(video): make player collapse follow scroll directly
pgs666 Jun 1, 2026
4f1e98e
fix(video): stabilize refresh and tab collapse
pgs666 Jun 1, 2026
e4c7b63
fix(video): remove detail tab pull refresh
pgs666 Jun 1, 2026
f12c959
fix(video): drive collapse by scroll delta
pgs666 Jun 1, 2026
d583aa5
fix(video): disable detail scroll bounce
pgs666 Jun 1, 2026
9a6f072
fix(video): harden detail gestures
pgs666 Jun 1, 2026
b1e92e7
revert(video): remove detail bounce disabler
pgs666 Jun 1, 2026
1a1feb1
fix(video): reliably disable detail scroll bounce
pgs666 Jun 1, 2026
3f26b1c
fix(video): lock vertical scroll during horizontal paging
pgs666 Jun 1, 2026
f5642fd
fix(video): extend detail content to bottom edge
pgs666 Jun 1, 2026
870a8eb
fix(video): avoid excess blank scroll filler
pgs666 Jun 1, 2026
8aed844
fix(video): keep detail scroll insets stable
pgs666 Jun 1, 2026
456fa4b
feat(comment): show end of list footer
pgs666 Jun 1, 2026
d188fbc
fix(video): gate vertical scroll with horizontal pan
pgs666 Jun 1, 2026
bbff52d
fix(video): restore reliable scroll range
pgs666 Jun 1, 2026
4e95852
fix(video): restore paging and playing scroll height
pgs666 Jun 2, 2026
45c3f8d
fix(video): prioritize horizontal pager pan
pgs666 Jun 2, 2026
e533a4c
fix(video): restore horizontal pager gesture
pgs666 Jun 2, 2026
fa6cc57
fix(video): arbitrate detail pager gestures
pgs666 Jun 2, 2026
f9d05f7
fix(video): load player when autoplay is disabled
pgs666 Jun 2, 2026
3eff9d5
fix(video): hide inline speed and quality controls
pgs666 Jun 2, 2026
80c3c2a
fix(video): sync paused state after autoplay load
pgs666 Jun 2, 2026
991ab5c
fix(video): refine playback layout and comment composer
pgs666 Jun 2, 2026
11435f9
fix(video): restore play state and composer inset
pgs666 Jun 2, 2026
26f9d90
fix(video): float comment composer above pager
pgs666 Jun 2, 2026
5e70d56
fix(video): lift comment composer above detail
pgs666 Jun 2, 2026
2478425
fix(video): add explicit composer layout return
pgs666 Jun 2, 2026
66dd0dd
fix(video): tune comment composer keyboard glass
pgs666 Jun 2, 2026
c5bb985
docs: record comment composer ci verification
pgs666 Jun 2, 2026
8b20332
fix(video): constrain ipad comment composer width
pgs666 Jun 2, 2026
2d48fae
fix(video): harden detail composer and orientation
pgs666 Jun 2, 2026
d0e459c
fix(video): return tablet sidebar predicate
pgs666 Jun 2, 2026
c00f95f
fix(comment): restore sort mode switching
pgs666 Jun 2, 2026
e40aa34
fix(comment): correct latest earliest order
pgs666 Jun 2, 2026
83424be
fix(comment): default to most liked sort
pgs666 Jun 2, 2026
288e14e
Probe scroll exclusion jank
pgs666 Jun 2, 2026
82ca545
Freeze collapse updates during tab switch
pgs666 Jun 2, 2026
ed10097
Revert "Freeze collapse updates during tab switch"
pgs666 Jun 2, 2026
3928545
Probe tab pager animation jitter
pgs666 Jun 2, 2026
9f18a75
Disable tab scroll content animations
pgs666 Jun 2, 2026
8aec004
Limit tab animation suppression to content
pgs666 Jun 2, 2026
e328c44
Revert "Limit tab animation suppression to content"
pgs666 Jun 2, 2026
2045616
Revert "Disable tab scroll content animations"
pgs666 Jun 2, 2026
ac86ca0
Revert "Probe tab pager animation jitter"
pgs666 Jun 2, 2026
a61c0ce
Use UIKit pager for video detail tabs
pgs666 Jun 2, 2026
9b04b7f
Use UIKit vertical tab scrollers
pgs666 Jun 2, 2026
6e17830
Preserve scroll compensation layout semantics
pgs666 Jun 2, 2026
2fe6f9c
Avoid rebuilding tab page content during scroll
pgs666 Jun 2, 2026
154c9f4
Use eager comment stack in UIKit scroller
pgs666 Jun 2, 2026
b2b8bcc
Match tab content padding offset semantics
pgs666 Jun 2, 2026
93e4208
Ensure tab scroll controllers are loaded before update
pgs666 Jun 2, 2026
c5130ae
Avoid setting UIScrollView pan delegate
pgs666 Jun 2, 2026
c4cf591
Stabilize keyboard and pause scroll transitions
pgs666 Jun 3, 2026
83d63b1
Respect horizontal sections in tab pager
pgs666 Jun 3, 2026
83aaf1b
Revert "Respect horizontal sections in tab pager"
pgs666 Jun 3, 2026
1976d1a
Revert "Stabilize keyboard and pause scroll transitions"
pgs666 Jun 3, 2026
cf4712b
Render comments incrementally after load
pgs666 Jun 3, 2026
e6aef8d
Use table view for video comments
pgs666 Jun 3, 2026
71e9485
Restore comment collapse compensation
pgs666 Jun 4, 2026
f425c95
Apply comment compensation inside table
pgs666 Jun 4, 2026
bba13bc
Preserve comment offset during inset compensation
pgs666 Jun 4, 2026
2ffe51c
Coordinate comment scroll collapse in table view
pgs666 Jun 5, 2026
e70df43
Freeze comment offset while player collapses
pgs666 Jun 5, 2026
de57589
Coordinate comment scroll expansion
pgs666 Jun 5, 2026
0b083f5
Let horizontal video lists own their pan
pgs666 Jun 5, 2026
b8cb17e
Detect nested horizontal scroll regions recursively
pgs666 Jun 5, 2026
76f2c6e
Stabilize related video card title height
pgs666 Jun 5, 2026
86ae67c
Let nested horizontal lists bypass vertical scroll pan
pgs666 Jun 5, 2026
7252521
Scroll detail tabs over fixed player
pgs666 Jun 5, 2026
df49975
Scroll detail panel over fixed player
pgs666 Jun 5, 2026
8785e0e
Clean comment panel scroll handling
pgs666 Jun 5, 2026
fb5f505
Remove manual player collapse
pgs666 Jun 5, 2026
8b208e7
Fix comment table collapse type
pgs666 Jun 5, 2026
d736daf
Clamp scroll collapse offset during bounce
pgs666 Jun 5, 2026
0cb9b4b
Use SwiftUI comments in detail pager
pgs666 Jun 5, 2026
082e4aa
Stabilize video detail scrolling
pgs666 Jun 5, 2026
7b86205
Stabilize video detail tab transitions
pgs666 Jun 5, 2026
acd71b9
Fix video detail tab transition build
pgs666 Jun 5, 2026
62e637c
Stabilize related video card thumbnails
pgs666 Jun 5, 2026
56fa8d2
Handle portrait related video thumbnails
pgs666 Jun 5, 2026
27c87ca
Refactor video detail pager
pgs666 Jun 5, 2026
a250d46
Fix comment pager top and keyboard glass
pgs666 Jun 5, 2026
7bb5983
Fix comment tab activation offset
pgs666 Jun 5, 2026
323d807
Stabilize comment pager scrolling
pgs666 Jun 5, 2026
0137624
Stabilize comment scroll alignment
pgs666 Jun 5, 2026
9430850
Throttle pager state while scrolling
pgs666 Jun 5, 2026
f0c9365
Fix comment pager scroll alignment
pgs666 Jun 6, 2026
bd8afc3
Avoid recursive comment pager layout
pgs666 Jun 6, 2026
cd45356
Use inset based pager top alignment
pgs666 Jun 6, 2026
b26f6e9
Refactor comment pager smooth scroll model
pgs666 Jun 6, 2026
f3d1ca2
Refactor video pager to stable header layout
pgs666 Jun 7, 2026
7322684
Sync pager header offsets across tabs
pgs666 Jun 7, 2026
8b8067f
Centralize video pager header geometry
pgs666 Jun 7, 2026
8041f5a
Ignore vertical pager updates during horizontal paging
pgs666 Jun 7, 2026
d868045
Preserve initial pager header offsets
pgs666 Jun 7, 2026
88a24a3
Add pager list header carrier
pgs666 Jun 7, 2026
0d3c8b2
Extract video detail pager coordinator
pgs666 Jun 7, 2026
d6eaed2
Centralize pager list offset context
pgs666 Jun 7, 2026
b8105e1
Reset pager list offset during content growth
pgs666 Jun 7, 2026
73f8355
Align video pager offset settlement with JX
pgs666 Jun 7, 2026
32728b6
Fix pager content size settling
pgs666 Jun 7, 2026
ffb5116
Preserve pager pending offset intent
pgs666 Jun 7, 2026
63d2440
Keep inactive pager offset pinned
pgs666 Jun 7, 2026
a02b28f
Extract pager offset model
pgs666 Jun 7, 2026
cb36a47
Report pager offset after horizontal settle
pgs666 Jun 7, 2026
4ce838d
Move pager pin header into list header lifecycle
pgs666 Jun 7, 2026
12a559a
Stop resetting pager offset on content updates
pgs666 Jun 7, 2026
008a747
Move continuation strip into pager header
pgs666 Jun 7, 2026
889780e
Stabilize pager header host updates
pgs666 Jun 7, 2026
fe174ff
Track pager header index during horizontal scroll
pgs666 Jun 7, 2026
8853012
Model pager inactive sync states
pgs666 Jun 7, 2026
4dbc47f
Align pager activation with JX semantics
pgs666 Jun 7, 2026
f562c39
Reapply pager activation after content resize
pgs666 Jun 7, 2026
3910c81
Model pager header sync state
pgs666 Jun 7, 2026
b555d72
Consolidate pager horizontal position
pgs666 Jun 7, 2026
a108454
Normalize pager horizontal finish handling
pgs666 Jun 7, 2026
9b414fe
Model pager header attachment state
pgs666 Jun 7, 2026
3d0e3e7
Consolidate list alignment state
pgs666 Jun 7, 2026
676ef18
Settle pager after selected state updates
pgs666 Jun 7, 2026
b599cd2
Sync inactive pager lists during vertical scroll
pgs666 Jun 7, 2026
e1655ee
Use content spacer for pager bottom clearance
pgs666 Jun 7, 2026
9a0bd17
Avoid treating pending alignment as user scroll
pgs666 Jun 7, 2026
a49c1fe
Use table-backed comment list
pgs666 Jun 7, 2026
c31c75e
Prepare comment table controller for pager
pgs666 Jun 7, 2026
764eaf2
Allow pager pages to use injected scroll views
pgs666 Jun 7, 2026
f83615b
Render comment page through table model
pgs666 Jun 7, 2026
3e0c9b1
Use native comment table in detail pager
pgs666 Jun 7, 2026
807da0c
Stabilize native comment table updates
pgs666 Jun 7, 2026
f4f6d56
Separate native list minimum height
pgs666 Jun 7, 2026
439b364
Forward native comment table scroll delegate
pgs666 Jun 7, 2026
0f4d4b0
Remove embedded comment table fallback
pgs666 Jun 7, 2026
5af3d7e
Align detail pager settling with smooth paging
pgs666 Jun 7, 2026
0073642
Simplify detail pager activation alignment
pgs666 Jun 7, 2026
9715d99
Make pager alignment event driven
pgs666 Jun 7, 2026
747c34d
Settle pager with target index
pgs666 Jun 7, 2026
a2720b9
Avoid full comment reload for action state
pgs666 Jun 7, 2026
6802d73
Avoid full comment reload for like state
pgs666 Jun 7, 2026
449758c
Align native comments pager with smooth list layout
pgs666 Jun 7, 2026
ed0d222
Keep smooth header stable during horizontal paging
pgs666 Jun 7, 2026
e3ea9d3
Sync inactive pager lists directly
pgs666 Jun 7, 2026
f7dd7d2
Activate pager lists with current header offset
pgs666 Jun 7, 2026
c941749
Keep visual top separate from activation offset
pgs666 Jun 7, 2026
dcd775b
Resolve native pager alignment after content sizing
pgs666 Jun 7, 2026
cd2bd09
Apply native pager offsets directly
pgs666 Jun 7, 2026
48cdd32
Route native pending alignment through direct offsets
pgs666 Jun 7, 2026
3af83f8
Stabilize comments pager activation
pgs666 Jun 7, 2026
a1ef34a
Simplify smooth pager horizontal state
pgs666 Jun 7, 2026
d78b2ed
Direct native list pager offsets
pgs666 Jun 7, 2026
ff00156
Separate native pager geometry alignment
pgs666 Jun 7, 2026
393347d
Stabilize comment row height estimates
pgs666 Jun 7, 2026
dbb96a0
Align comment pager with smooth header model
pgs666 Jun 7, 2026
2dc2c59
Stabilize native comment list update ordering
pgs666 Jun 7, 2026
5f4a629
Cache measured comment row heights
pgs666 Jun 7, 2026
ff11694
Coalesce measured comment height updates
pgs666 Jun 7, 2026
b13f8b7
Fix non-comment table row heights
pgs666 Jun 7, 2026
8fabffd
Defer pager selection during horizontal scroll
pgs666 Jun 7, 2026
c0a1c50
Avoid resync after horizontal pager settle
pgs666 Jun 7, 2026
03fe93f
Limit native initial offset maintenance
pgs666 Jun 7, 2026
af22510
Remove stale pager alignment state
pgs666 Jun 7, 2026
b812884
Stop active comment offset relayout
pgs666 Jun 7, 2026
c8aeace
Simplify horizontal pager settlement
pgs666 Jun 7, 2026
f347121
Unify active header sync path
pgs666 Jun 7, 2026
46af748
Separate SwiftUI pending alignment
pgs666 Jun 7, 2026
1797a1e
Silence internal offset alignment writes
pgs666 Jun 7, 2026
e516a1e
Use inset for native comment clearance
pgs666 Jun 7, 2026
286a91c
Use explicit inset for pager offsets
pgs666 Jun 7, 2026
698d02d
Defer inactive native list alignment
pgs666 Jun 7, 2026
745e0cd
Keep inactive native reset pending
pgs666 Jun 7, 2026
67855a4
Refresh selection during pager settlement
pgs666 Jun 7, 2026
eab528f
Make pager settlement idempotent
pgs666 Jun 7, 2026
feb16a5
Avoid redundant pending pager selection
pgs666 Jun 7, 2026
5a79bc1
Stabilize comment pager activation
pgs666 Jun 7, 2026
0323e43
Keep native pager alignment pending
pgs666 Jun 7, 2026
916a856
Track active header during paging
pgs666 Jun 7, 2026
3dff5d6
Defer inactive sync while paging
pgs666 Jun 7, 2026
d77ddae
Use controller selection for native alignment
pgs666 Jun 7, 2026
47c195c
Stabilize native comments pager alignment
pgs666 Jun 7, 2026
0ee1ad8
Settle horizontal pager state atomically
pgs666 Jun 7, 2026
59351a3
Keep inactive native sync pending until reachable
pgs666 Jun 7, 2026
1afd620
Decouple inactive sync from header attachment
pgs666 Jun 7, 2026
0c8ec12
Unify list pending alignment state
pgs666 Jun 7, 2026
cbf0463
Protect native pager initial alignment
pgs666 Jun 7, 2026
a366d58
Move comment bottom clearance to table footer
pgs666 Jun 7, 2026
22b61a3
Finish native initial alignment after stable layout
pgs666 Jun 7, 2026
39daf34
Stop native comment refresh resetting pager offset
pgs666 Jun 7, 2026
f5b0032
Finish native alignment before first vertical drag
pgs666 Jun 7, 2026
ee26e7e
Keep pager header in root view hierarchy
pgs666 Jun 7, 2026
178fc55
Guard pager header root attachment in CI
pgs666 Jun 7, 2026
b4d3acb
Reduce comment pager scroll intervention
pgs666 Jun 7, 2026
1b338bc
Simplify video pager scroll alignment
pgs666 Jun 7, 2026
c9e427a
Use self sizing comment cells
pgs666 Jun 7, 2026
d94b513
Set comment table estimated row height
pgs666 Jun 7, 2026
dea507b
Simplify pager header page state
pgs666 Jun 7, 2026
c67e5de
Apply initial native pager offset
pgs666 Jun 7, 2026
aa31bf5
Stabilize comment row sizing
pgs666 Jun 7, 2026
7ec7db0
Keep native comment bottom inset owned by table
pgs666 Jun 7, 2026
b488a4e
Flatten pager inactive offset sync
pgs666 Jun 7, 2026
e706840
Stop mutating native comment content size
pgs666 Jun 7, 2026
a568d1a
Apply pager initial offset on selection
pgs666 Jun 7, 2026
b8a77b3
Remove comment row height estimates
pgs666 Jun 7, 2026
87f45d2
Gate native comment updates by revision
pgs666 Jun 7, 2026
2d36b89
Let active vertical lists keep touch priority
pgs666 Jun 7, 2026
9c57f37
Reduce tablet intro bottom clearance
pgs666 Jun 7, 2026
4656d2b
Fix comment row self sizing
pgs666 Jun 7, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ios-app-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ jobs:
- name: Run shared JVM tests
run: ./gradlew :shared:jvmTest --no-daemon

- name: Check video pager structure
run: bash scripts/check_video_pager_structure.sh

- name: Generate Xcode project
run: xcodegen generate

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ jobs:
- name: Run shared JVM tests
run: ./gradlew :shared:jvmTest --no-daemon

- name: Check video pager structure
run: bash scripts/check_video_pager_structure.sh

- name: Generate Xcode project
run: xcodegen generate

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Agent Log: Video Detail Horizontal Pager Gesture

## User Input

Original:

```text
查看 han1viewer-ios这个库,并调查:为什么视频详情页的横滑手势完全失效了
修复它:我想要的效果是,触发横滑之后完全不触发滚动,同理触发滚动后完全不触发横滑,尝试做完整的修复
需要推送触发pr进行ci编译
```

English translation:

```text
Inspect the han1viewer-ios repository and investigate why the horizontal swipe gesture on the video detail page is completely broken.
Fix it: the desired behavior is that once horizontal paging is triggered, scrolling must not trigger at all; likewise once scrolling is triggered, horizontal paging must not trigger at all. Try to make a complete fix.
Push it to trigger PR CI compilation.
```

## What Changed

- Reworked the video detail tab pager gesture arbitration in `iosApp/VideoDetailView.swift`.
- Replaced the background ancestor-level horizontal pan installer with a coordinator that installs a dedicated horizontal paging `UIPanGestureRecognizer` directly on each tab-owned `UIScrollView`.
- Made each vertical `UIScrollView.panGestureRecognizer` require the horizontal paging pan to fail before vertical scrolling can begin.
- Kept simultaneous recognition disabled, so horizontal paging and vertical scrolling cannot both win for the same touch sequence.
- Moved SwiftUI state callbacks into the `UIViewRepresentable` coordinator and weakly referenced them from the shared gesture coordinator to avoid retaining the page through closure chains.

## Why

The previous implementation depended on a SwiftUI background view walking up a private UIKit view hierarchy and attaching the horizontal pan to a guessed ancestor view. The tab contents are themselves `ScrollView`s, so the nested vertical scroll recognizer could win the gesture before horizontal paging ever reached `.began`.

The new implementation puts both recognizers in the same `UIScrollView` gesture arena and establishes an explicit failure dependency:

- Horizontal-looking gestures satisfy the custom pan's `gestureRecognizerShouldBegin`, so the scroll view pan fails and no vertical scroll happens.
- Vertical-looking gestures fail the custom pan, allowing the scroll view pan to proceed normally.

## Mistakes Or Failed Attempts

- The first local edit kept horizontal callbacks directly on `VideoDetailGestureCoordinator`. I changed that before committing because the coordinator is owned by SwiftUI state and those escaping closures can retain view state longer than intended.
- The first edit also left a short-drag no-page-change path that could keep a non-zero pager translation. I changed `finishHorizontalPaging` so it always resets the visual translation.

## Verification

- Ran `git diff --check`; it passed.
- Checked this environment for `xcodebuild` and `swiftc`; neither is available on this Linux aarch64 machine, so local Swift/iOS compilation cannot be performed here.

## Known Limits

- iOS build and runtime gesture verification must be done by GitHub Actions/macOS and a device or simulator test.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Agent Log: Hide Series Video Metadata Footer

## User Input

Original:

```text
目前版本的“系列影片”一栏和界面都有问题,标题卡片下方的作者和发布时间没法正常显示。
那就不需要实现了,直接对这个系列影片特殊处理,不显示那一行
```

English translation:

```text
In the current version, the "Series Videos" section and UI have problems; the author and publish time under the title card cannot display normally.
Then there is no need to implement parsing; just special-case this Series Videos section and do not show that line.
```

## What Changed

- Added a `showsMetadataFooter` flag to `RelatedVideoCard`.
- Passed that flag through `HorizontalVideoSection` and `RelatedVideoListView`.
- Set `showsMetadataFooter: false` for the video detail "系列影片" section only.

## Why

The series playlist data currently does not reliably include author and upload-time metadata, and the user requested a direct UI special case instead of parser work. Hiding the footer avoids placeholder or broken-looking metadata in both the inline horizontal section and the "更多" list.

## Verification

- Ran `git diff --check`; it passed.
- Checked Swift call sites for `HorizontalVideoSection`, `RelatedVideoListView`, and `RelatedVideoCard`.

## Known Limits

- This intentionally does not add series playlist author/upload-time parsing.
- This Linux environment cannot run Xcode/iOS compilation locally.
35 changes: 35 additions & 0 deletions docs/agent-logs/2026-06-02-1758-fix-autoplay-load-paused.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Agent Log: Fix Autoplay Disabled Loading

## User Input

Original:

```text
接下来修复“打开视频时自动播放”这个开关。预期的行为是关闭这个开关后正常加载但是加载出之后不开始播放,但是现在的行为是连加载都不开始,改了它并推送
```

English translation:

```text
Next, fix the "auto-play when opening a video" switch. The expected behavior is that after turning it off, the video still loads normally but does not start playing after it has loaded. The current behavior is that loading does not even start. Change it and push it.
```

## What Changed

- Updated `KSPlayerView.makeKSOptions` so `KSOptions.isAutoPlay` stays `true`.
- Left the user preference enforcement in `onStateChanged`: once KSPlayer reaches `.bufferFinished`, the app calls `play()` or `pause()` according to `autoPlayOnEnter`.
- Updated the diagnostic mount log label from `ksAutoPlay` to `ksLoadAutoPlay` to make the distinction explicit.

## Why

KSPlayer uses `KSOptions.isAutoPlay` as part of whether it begins opening/buffering the URL. Binding it directly to the user preference caused the "auto-play off" state to prevent loading entirely. Keeping the KSPlayer loading switch on and pausing after the first ready state matches the intended behavior: load the video, but wait for user input before playback.

## Verification

- Ran `git diff --check`; it passed.
- Ran `./gradlew :shared:jvmTest`; it passed.
- PR CI will verify Swift/iOS compilation after push.

## Known Limits

- This Linux environment cannot run Xcode/iOS compilation locally.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Agent Log: Hide Inline Player Speed And Quality Controls

## User Input

Original:

```text
能不能让播放器在不全屏的时候不显示播放倍速和视频画质的按钮?全屏后再显示,防止让进度条变成短短的一条
```

English translation:

```text
Can the player hide the playback speed and video quality buttons when it is not fullscreen, and show them only after entering fullscreen, so the progress bar does not become very short?
```

## What Changed

- Updated `iosApp/KSPlayerView.swift` so the playback speed menu and quality menu are only rendered when `isFullscreen` is true.
- Left the fullscreen button visible in both inline and fullscreen modes.
- Preserved the existing behavior that the quality menu only appears when there is more than one playback source.

## Why

The inline video player has limited horizontal space. Rendering play/pause, timestamps, the progress slider, playback speed, quality, and fullscreen controls in one row made the slider too short. Hiding speed and quality while inline keeps the main playback controls usable, while still exposing those menus in fullscreen where there is enough room.

## Mistakes Or Failed Attempts

- None.

## Verification

- `git diff --check` passed.
- `./gradlew :shared:jvmTest` passed on local Linux aarch64. Kotlin/Native is still unsupported on this host, so the actual iOS Swift build is left to GitHub Actions.

## Known Limits

- This is a visibility/layout change only. The selected playback rate and source state are unchanged.
38 changes: 38 additions & 0 deletions docs/agent-logs/2026-06-02-1824-fix-autoplay-paused-state.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Agent Log: Fix Autoplay Disabled Paused State

## User Input

Original:

```text
自动播放修复的逻辑有一点点小问题:加载好后播放器没有认为自己是暂停状态,双击之后反而是暂停,顺便还导致了加载好之后视频没有在播放但是上下滑动下方view时不会让视频自动收起
另外,记得使用--exit-status来监控
```

English translation:

```text
There is a small issue with the autoplay fix: after loading, the player does not think it is paused. Double-tapping pauses instead, and after loading the video is not playing but scrolling the lower view does not automatically collapse the video. Also, remember to use --exit-status for monitoring.
```

## What Changed

- Updated `iosApp/KSPlayerView.swift` so the first `.bufferFinished` autoplay enforcement also updates the local `isPlaying` value with the action that was actually applied.
- When `auto_play_on_enter` is disabled, the player still loads, then pauses, and now explicitly reports paused state to the parent view.

## Why

The previous fix paused the KSPlayer layer after buffering, but then continued to copy `state.isPlaying` from the original `.bufferFinished` callback. That old value could remain true even after `layer.pause()`, leaving SwiftUI and `VideoDetailView` believing playback was active. This broke double-tap play/pause semantics and prevented the paused-only scroll collapse behavior.

## Mistakes Or Failed Attempts

- The first autoplay-disabled loading fix handled the media loading behavior but missed the SwiftUI playing-state mirror used by controls and parent layout.

## Verification

- `git diff --check` passed.
- `./gradlew :shared:jvmTest` passed on local Linux aarch64. Kotlin/Native remains unsupported on this host, so the iOS Swift build is verified through GitHub Actions with `--exit-status`.

## Known Limits

- This fixes state mirroring for the autoplay-disabled startup pause. It does not change KSPlayer's underlying state enum semantics.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Agent Log: Playback Layout Review Fixes And Comment Composer

## User Input

Original:

```text
把你总结的五个问题一个一个修复。顺便把评论区的发送评论按钮换成输入框放在屏幕底部,使用原生组件(iOS26时为透明玻璃,之前的系统版本兼容成普通的屏幕底部输入框
```

English translation:

```text
Fix the five issues you summarized one by one. Also replace the comment area's send-comment button with an input field at the bottom of the screen, using native components: transparent glass on iOS 26, and a normal bottom-screen input field on earlier system versions.
```

## What Changed

- Updated fullscreen player controls to respect safe-area insets, so top and bottom chrome avoid notches, rounded corners, and the home indicator.
- Made the player bottom control bar responsive: time labels hide on narrow widths and the progress slider gets layout priority.
- Fixed the manually collapsed player strip layout so the lower content uses the visible 50-point strip height instead of reserving the larger follow-collapse minimum height.
- Tightened the iPad two-column threshold so the related sidebar only appears when there is enough width for both a 620-point player column and a 360-point sidebar.
- Constrained long tag chips to a single truncated line so they cannot push the detail page wider than the screen.
- Removed the main comment compose button from the comment header and added a native bottom comment composer on the comments tab.
- Used SwiftUI's iOS 26 `glassEffect` for the bottom composer chrome, with a `regularMaterial` rounded container fallback on earlier iOS versions.
- Made `CommentViewModel.postComment(text:)` report whether a send actually started, so the bottom composer only clears after local validation passes.

## Why

The playback page had several layout edges that were individually small but visible on real devices: fullscreen controls could sit too close to unsafe screen edges, the progress slider could still be squeezed, collapsed-player content had a bottom-height mismatch, iPad split mode activated too early, and long tags could overflow. The comment action also required a modal sheet for a short message, while the desired interaction is a persistent native composer at the bottom of the comments screen.

## Mistakes Or Failed Attempts

- None.

## Verification

- `git diff --check` passed.
- `./gradlew :shared:jvmTest` passed on local Linux aarch64. Kotlin/Native is unsupported on this host, so iOS/Swift verification must run on GitHub Actions with Xcode 26.

## Known Limits

- The iOS 26 glass API is guarded with `#available(iOS 26.0, *)`; final validation depends on the CI Xcode 26 build.
- Reply composition still uses the existing sheet flow; this change only replaces the main comment composer button.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Agent Log: Fix Player State And Comment Composer

## User Input

Original:

```text
那个输入栏改的不好。你先搜搜有没有最佳实现。另外你把播放器改坏了,现在(关闭打开视频时自动播放功能)正在播放的时候播放器不会认为正在播放,导致双击播放暂停等等功能全部失效了
```

English translation:

```text
That input bar change is not good. First search for a best-practice implementation. Also, you broke the player: now when "autoplay on opening video" is disabled, while the video is playing the player does not think it is playing, which breaks double-tap play/pause and related features.
```

## What Changed

- Reworked the main comment composer so it is attached to the comments `ScrollView` with `safeAreaInset(edge: .bottom)` instead of a manual screen-covering overlay.
- Kept the composer as a native bottom bar: iOS 26 uses SwiftUI `glassEffect` on the input field; older iOS versions use a normal `.bar` bottom background with a system secondary input capsule.
- Switched the composer to `TextField(_:text:axis:)` with a 1-to-4-line limit, so short comments stay compact and longer comments can grow without opening a sheet.
- Fixed the player playing-state mirror by updating SwiftUI state immediately when user actions call `play()` or `pause()`.
- Stopped treating a non-playing `.bufferFinished` callback as authoritative after autoplay enforcement, so KSPlayer's ready/buffered state no longer overwrites manual play state.

## Why

Apple's SwiftUI layout APIs support inserting bottom UI with safe-area-aware modifiers instead of manually overlaying controls and guessing heights. The previous implementation manually placed the composer over the whole detail panel and padded the scroll content by an estimated height, which is fragile around keyboard, home indicator, paging, and rotation.

The player regression came from relying on KSPlayer's state callback to mirror playing state. With autoplay disabled, the layer is intentionally paused after buffering, but later manual `play()` can leave the callback in `.bufferFinished` while playback is active. The UI state must mirror explicit user play/pause commands as well.

## Mistakes Or Failed Attempts

- The previous composer implementation used a manual overlay and reserved-height padding instead of safe-area insertion.
- The previous autoplay-disabled fix synchronized the initial paused state, but did not keep later manual play/pause transitions authoritative.

## Verification

- `git diff --check` passed.
- `./gradlew :shared:jvmTest` passed on local Linux aarch64. Kotlin/Native is unsupported on this host, so the iOS Swift build is verified through GitHub Actions.

## Known Limits

- The iOS 26 glass appearance is compile-guarded with `#available(iOS 26.0, *)`; final Swift API verification is done by CI on Xcode 26.
36 changes: 36 additions & 0 deletions docs/agent-logs/2026-06-02-1922-float-comment-composer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Agent Log: Float Comment Composer

## User Input

Original:

```text
评论按钮实现依然不对:我希望它悬浮在简介/评论 view上面,检测到在评论view里面就自动出现,如果不在就自动消失,而不是把它整个放进评论区的scroll view里面。然后这个输入框我希望它能跟随输入法上边缘浮起,而不是被输入法挡住。先搜索再做
```

English translation:

```text
The comment button implementation is still wrong: I want it to float over the introduction/comments views, automatically appear when the comments view is active, and disappear when it is not. It should not be placed inside the comments scroll view. The input field should also float with the keyboard's top edge instead of being covered by the keyboard. Search first, then implement.
```

## What Changed

- Moved the main comment composer out of the comments `ScrollView`.
- Mounted the composer as a floating overlay on the introduction/comments pager container.
- The composer now appears only when the active tab is `.comments`, and disappears on `.introduction`.
- Marked the floating composer as a horizontal-pager exclusion area so input/button touches do not trigger page swipes.
- Stopped ignoring keyboard safe-area regions in inline video detail mode by switching to container-only safe-area ignoring, and only in fullscreen.
- Added interactive keyboard dismissal to the tab scroll views.
- Added a little extra bottom padding to the comments content so the floating composer does not cover the last visible comments.

## Why

Apple's SwiftUI safe-area model treats keyboard avoidance as a safe-area adjustment. The previous root-level safe-area ignore used the default safe-area regions, which can include the keyboard region. Keeping inline mode inside the keyboard-safe layout lets the floating composer move with the keyboard without manual keyboard-height observers.

The previous composer was attached to the comments `ScrollView` as a bottom inset. That made it part of the scroll view's layout instead of a layer controlled by the active pager tab.

## Verification

- `git diff --check` passed.
- `./gradlew :shared:jvmTest` passed on local Linux aarch64. Kotlin/Native remains unsupported on this host, so the iOS Swift build is verified through GitHub Actions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Agent Log: Anchor Comment Composer Safe Area

## User Input

Original:

```text
能不能把评论框铆定在屏幕内部?现在还是会出屏幕外。另外现在安全区设计又出问题了,scrollview无论何时都与屏幕最下面有一层gap
```

English translation:

```text
Can you anchor the comment box inside the screen? It still goes outside the screen now. Also the safe-area design is broken again: the scroll view always has a gap above the bottom of the screen.
```

## What Changed

- Restored inline video-detail content to ignore only the container bottom safe area, not the keyboard safe area.
- Passed the outer geometry bottom safe-area inset into the floating comment composer.
- Added the bottom safe-area inset inside the composer chrome so the input field stays above the home indicator.
- Increased comments tab bottom content clearance by the same inset so the floating composer does not cover the last comments.

## Why

The previous change stopped ignoring the container bottom safe area in inline mode. That fixed keyboard avoidance but reintroduced the visible bottom gap under the pager/scroll area. The correct split is to ignore only `.container` bottom for the page, while keeping keyboard safe-area avoidance active. The floating composer then needs its own bottom inset so it remains inside the screen.

## Verification

- Superseded by the root-level composer change logged in `2026-06-02-1942-root-comment-composer.md`.
- Local checks and GitHub Actions CI are run after both changes together.
Loading