Skip to content

feat(tv): row actions on Files: VLC, watched toggle, trash or delete - #171

Merged
altaywtf merged 5 commits into
mainfrom
feat/tv-files-actions
Sep 12, 2026
Merged

altaywtf merged 5 commits into
mainfrom
feat/tv-files-actions

Conversation

@altaywtf

Copy link
Copy Markdown
Member

Part of #33 (Files long-press action menu, oracle files-actions state). Needs putdotio/putio-sdk-kotlin#52 (merged as 2c61413).

Problem

TV Files rows could only be opened. The oracle's Android baseline offers a long-press menu per row: VLC handoff with the original stream URL, Mark watched / unwatched, and Trash or Delete per the account's Trash setting. None of it existed on TV.

Solution

Long-press Center or the Menu key on a row opens TvFilesActionsDialog (app/src/tv/.../tv/files/TvFilesActions.kt), a centred dialog titled with the file name, one full-width button per action, Cancel last, first action focused:

  • Open in VLC (media rows): the original /files/{id}/stream URL from the new FilesStreamUrls goes to org.videolan.vlc as ACTION_VIEW data only. A dialog explains when VLC is not installed or no session token is set.
  • Mark as watched / unwatched (videos, only while the account's confirmed use_start_from is on; marking watched also needs a known duration): TvSession.setWatched writes the duration or clears the position through the new FilesWatchedRepository, then dispatches PlaybackPositionReported so the row updates. Failures show as a dismissible dialog; a 401 rejects the session.
  • Move to trash / Delete permanently (only when the confirmed trash_enabled is known and the folder is idle): confirms with Cancel focused, then dispatches the shared FilesBrowserEvent.Delete. The pane shows the operation's phases above the rows, Check status or Retry when it fails, and the fresh listing's verdict once settled.

Dialog state is saveable per session and folder, closes when the row leaves the listing, and every close returns focus to the row.

Proof

./gradlew verify :buildSrc:test :app:assembleTvProductionDebug :app:assembleMobileProductionDebug green; TvFilesScreenTest (+3), TvSessionViewModelTest (+2).

Live on the API 36 TV emulator with devs-auto: Menu opened the actions on a video row; Mark as watched wrote the 10 s duration (files.getStartFrom → 10) and the row read “100% watched”; Mark as unwatched read back 0; Open in VLC showed the not-installed dialog (no VLC on the emulator, so the handoff itself is unproven); Move to trash on a fixture text file confirmed, ran, reported “no longer in Files”, and trash.list shows it. Captures follow in a comment.

Long-press Center or the Menu key on a Files row opens the oracle's actions
dialog: Open in VLC hands the original stream URL to org.videolan.vlc, Mark
as watched or unwatched writes the account's position through the new
FilesWatchedRepository (only when the account keeps positions), and Move to
trash or Delete permanently follows the confirmed Trash setting, confirms
first, and runs the shared delete operation whose phases and verdict show
above the rows. Every dialog returns focus to its row.
Copilot AI lite review requested due to automatic review settings September 12, 2026 15:43
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 12, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-12T16:40:30.660327Z 98d8190 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@altaywtf

Copy link
Copy Markdown
Member Author

Live proof on the API 36 TV emulator, devs-auto identity (evidence links expire):

State Capture
Menu key on a video row: Open in VLC, Mark as watched, Move to trash, Cancel (oracle files-actions) screenshot
After Mark as watched: row reads 100% watched, focus back on the row; files.getStartFrom → 10 screenshot
Open in VLC without VLC installed screenshot
Move to trash? confirmation, Cancel focused screenshot
Outcome above the rows after the fresh listing: no longer in Files (trash.list shows the file) screenshot

Mark as unwatched read back 0 through files.getStartFrom. The VLC handoff itself is unproven here: the emulator has no VLC, so only the missing-player path was exercised.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

The implementation matches the stated TV Files row-actions behavior and adds focused tests; only a minor unused-string cleanup was noted.

Pull request overview

Adds TV “row actions” parity to the Files screen by introducing a long-press/Menu-key action dialog and wiring it into the TV session, including VLC handoff, watched/unwatched toggling, and trash/delete flows consistent with the shared Files browser operation model.

Changes:

  • Introduces TvFilesActionsDialog / delete confirmation dialog and row key handling (Menu + long-press) on TV Files rows.
  • Adds watched-position and original-stream-url dependencies to the TV session (FilesWatchedRepository, FilesStreamUrls) and connects them from the TV app runtime.
  • Expands TV test coverage for menu actions, watched toggling behavior, and delete-status UI.
File summaries
File Description
README.md Updates TV feature overview to mention Files row actions and delete status reporting.
docs/harness.md Documents a concrete proof script/flow for the new TV Files actions oracle state.
app/src/tv/res/values/strings.xml Adds strings for the TV Files actions UI and delete status/notice copy.
app/src/tv/kotlin/io/putdotio/android/tv/TvSessionViewModel.kt Adds session APIs and state for watched toggling failures and original stream URL access.
app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt Implements actions dialog state, focus return behavior, delete-status banner, and row Menu-key handling.
app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesActions.kt Adds the TV actions model, dialogs, and VLC intent launcher.
app/src/tv/kotlin/io/putdotio/android/PutioApp.kt Wires new repos into dependencies and connects Files screen callbacks for VLC + watched toggling + notices.
app/src/testTv/kotlin/io/putdotio/android/tv/TvSessionViewModelTest.kt Adds tests for watched write behavior, failure reporting, and stream URL availability.
app/src/testTv/kotlin/io/putdotio/android/tv/files/TvFilesScreenTest.kt Adds UI tests for Menu-key actions, delete confirmation, action availability rules, and delete-status UI.
app/src/main/kotlin/io/putdotio/android/files/FilesWatchedRepository.kt Adds SDK-backed repository for watched position writes and stream URL provider types.
Review details
  • Files reviewed: 10/10 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/src/tv/res/values/strings.xml Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fe265b100a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt
Comment thread app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesActions.kt
Comment thread app/src/tv/kotlin/io/putdotio/android/tv/TvSessionViewModel.kt Outdated
…ized watched writes

The chosen trash mode is kept while the confirmation is up and a setting
that changes underneath withdraws it; a failed delete reports only through
its own status line; a media file without a position keeps its duration so
it can be marked watched; a newer watched write supersedes an unfinished one.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

The VLC launch intent currently always uses FLAG_ACTIVITY_NEW_TASK, which can break expected back-stack behavior when launching from an Activity context.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesActions.kt:116

  • launchVlc always sets FLAG_ACTIVITY_NEW_TASK, which changes task/back-stack behavior when launching from an Activity context (e.g., Back from VLC may go Home instead of returning to the app). It’s safer to add this flag only when the provided Context isn’t an Activity (still avoiding the "Calling startActivity from outside of an Activity" crash for app-context calls).
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdf60ad84b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/tv/kotlin/io/putdotio/android/tv/TvSessionViewModel.kt Outdated
Comment thread app/src/tv/kotlin/io/putdotio/android/PutioApp.kt

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

There’s a race/cancellation correctness issue in TvSession.setWatched where an older cancelled job can still report results unless guarded, which can lead to stale UI/failure state.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesActions.kt:10

  • Unused import: FocusRequester isn’t referenced in this file (the dialog focus requester is provided as a lambda parameter), so this import is dead code and should be removed to keep the file clean.
  • Files reviewed: 12/12 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment thread app/src/tv/kotlin/io/putdotio/android/tv/TvSessionViewModel.kt Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

Deletion actions are enabled in some non-idle folder states despite the PR description stating they should be offered only when the folder is idle.

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt:289

  • The PR description says trash/delete should be offered only when the folder is idle, but the menu currently enables deletion whenever canStartOperation is true (which includes some failed-operation states like failed refresh/sort). If the intent is to match the stated behavior, gate deletion actions on FilesFolderOperation.Idle instead.
    app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt:679
  • onActions is documented as null when the row offers nothing beyond opening, but in the Files list every row is currently wired with a non-null onActions (so even rows with no available actions can open a Cancel-only dialog). Either pass null for rows with no actions, or adjust this KDoc so it matches the actual contract (null disables the actions affordance).
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 492cabc7dc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/src/tv/kotlin/io/putdotio/android/tv/TvSessionViewModel.kt Outdated
Comment thread app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt
…confirmation closes when the folder gets busy

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Needs a closer look

There are a couple of correctness/quality issues to address (notably an unused import that can break strict builds, and a misleading KDoc contract that doesn’t match current call sites).

Review details

Suppressed comments (2)

Previously missed (2) — in code that hasn't changed since the last review.

app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesActions.kt:10

  • Unused import FocusRequester in this file; it isn’t referenced and can trigger unused-import checks in static analysis. Remove it to keep the file warning-free.
    app/src/tv/kotlin/io/putdotio/android/tv/files/TvFilesScreen.kt:682
  • The KDoc for onActions says it is null when the row offers nothing beyond opening, but the list always passes a non-null lambda (onActions = { onActions(item) }), even when the actions list is empty. Update the comment so it matches the actual contract (null disables actions; non-null opens the actions menu).
  • Files reviewed: 12/12 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants