Skip to content

Feat android ios#13

Open
lbb00 wants to merge 45 commits into
mainfrom
feat-android-ios
Open

Feat android ios#13
lbb00 wants to merge 45 commits into
mainfrom
feat-android-ios

Conversation

@lbb00

@lbb00 lbb00 commented Jun 8, 2026

Copy link
Copy Markdown
Member

No description provided.

lbb00 and others added 30 commits March 16, 2026 00:28
- Extract opentivi-core shared Rust crate from desktop app
- Add Android TV client (Jetpack Compose for TV + UniFFI bridge)
- Add iOS client (SwiftUI + AVPlayer + UniFFI bridge)
- Update Makefile with build targets for all three platforms
- Update README with multi-platform tech stack and structure
- Add architecture docs for Android TV and iOS

Amp-Thread-ID: https://ampcode.com/threads/T-019cf24a-650d-75fb-94ed-3622d1240858
Co-authored-by: Amp <amp@ampcode.com>
- Documents/ exposes DB to user Files app and iCloud backup
- Application Support/ is Apple's recommended location for app data
- Add Xcode project (xcodegen) and project.yml

Amp-Thread-ID: https://ampcode.com/threads/T-019cf24a-650d-75fb-94ed-3622d1240858
Co-authored-by: Amp <amp@ampcode.com>
- Move RustBridge.initialize() to async initializeAsync() to avoid
  blocking the main thread on startup; show loading screen until ready
- Add LocaleManager that detects system language and loads translations
  from shared/locales JSON files
- Wire up language switching in SettingsView with LocaleManager
- Localize tab labels, navigation titles, and source action labels
- Add shared locale JSON files to Xcode project resources

Amp-Thread-ID: https://ampcode.com/threads/T-019cf81f-80dd-7465-97d9-6dd69f4155cf
Co-authored-by: Amp <amp@ampcode.com>
…erBar safe area padding

- Add UILaunchScreen to Info.plist so iOS uses native screen size instead
  of compatibility/letterboxed mode
- Replace hardcoded padding(.bottom, 49) with GeometryReader-based
  calculation that accounts for bottom safe area insets

Amp-Thread-ID: https://ampcode.com/threads/T-019cf81f-80dd-7465-97d9-6dd69f4155cf
Co-authored-by: Amp <amp@ampcode.com>
…ore UniFFI

All RustBridge stub methods now use an in-memory store instead of
returning empty arrays. Sources added via importM3u/importXtream appear
in fetchSources, deleteSource removes them, and settings persist in
memory. This makes the UI flow functional until UniFFI bindings are
wired up. Also removed nonisolated markers since all stub state is
on @mainactor.

Amp-Thread-ID: https://ampcode.com/threads/T-019cf81f-80dd-7465-97d9-6dd69f4155cf
Co-authored-by: Amp <amp@ampcode.com>
- Replace all stub/in-memory implementations in RustBridge.swift with
  real calls to UniFFI-generated free functions
- Add updateSource() method to RustBridge
- Wire EditSourceView Save button to RustBridge.shared.updateSource()

Amp-Thread-ID: https://ampcode.com/threads/T-019cfc76-a16f-72bb-b94f-2feda25e5d78
Co-authored-by: Amp <amp@ampcode.com>
… backend

- Add CoreContext (DbExecutor + reqwest::Client) as unified async context
- DbExecutor: spawn_blocking with connection-per-job, replacing Mutex<Connection>
- Convert all core services to async fn taking &CoreContext
- HTTP client: async reqwest, remove blocking feature
- proxy/remote_config/health_worker: tokio::spawn on shared runtime
  instead of std::thread::spawn + Runtime::new()
- Desktop Tauri: all commands async, no more state.db.lock().unwrap()
- iOS/Android UniFFI: shared tokio Runtime with block_on() bridge at FFI boundary
- std::fs::read_to_string → tokio::fs::read_to_string in import service

Amp-Thread-ID: https://ampcode.com/threads/T-019cfc8b-e0b7-767f-a7af-4053732d7254
Co-authored-by: Amp <amp@ampcode.com>
…ted types

- Move all synchronous Rust FFI calls off MainActor via Task.detached
- Fix corrupted [REDACTED:password] type annotations to String
- Fix initializeAsync() missing try on Task.detached .value
- Use @StateObject instead of @ObservedObject for singleton in App
- Add error handling/rollback for deleteSource, toggleFavorite, removeFavorite, editSource
- Fix RecentsView.relativeTime() stub to use existing Date+Formatting helpers
- Remove hardcoded 49pt tab bar height in MiniPlayerBar layout

Amp-Thread-ID: https://ampcode.com/threads/T-019d0737-1748-7293-bdf7-c87460a99c82
Co-authored-by: Amp <amp@ampcode.com>
- Switch Theme and Type to androidx.tv.material3
- Wire PlayerScreen to PlayerViewModel (exoPlayer, channel info, EPG, channel switching)
- Refactor ImportDialog to use Dialog/Card/TabRow from TV Material3
- Add Sources tab to navigation
- Simplify TiviPlayer: reuse play() in switchChannel(), remove unused annotations
- Clean up PlayerViewModel: remove redundant releasePlayer(), use onCleared()
- Add hilt-navigation-compose dependency

Amp-Thread-ID: https://ampcode.com/threads/T-019d0c8a-11d6-7596-a322-5fcc128065a1
Co-authored-by: Amp <amp@ampcode.com>
…esktop UI

- New android-phone app mirroring TV feature set (channels, player, favorites, recents, search, EPG)
- Android TV: player diagnostics/channel-list panels, EPG search, recents, spacing tokens, edit-source dialog
- iOS: overlay/player rework, expanded settings, sources editing, recents
- Desktop: UI component and design-token refresh
- Core: health worker, playback service, proxy rewrite refinements

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…l (P0a)

EPG 节目时间增量迁移第一步:新增可空 start_epoch/end_epoch(秒),
导入端双写、run_migrations 后幂等回填存量行;保留原 TEXT 列,不切读、不动 FFI。

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

多端方案基于 feat-android-ios 真实架构重写(6端 native+UniFFI/NAPI);
README 补齐 android-phone/harmony 两端;iOS 文档校正为 VLCKit 现状 + 选项2 决策。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
频道在刷新中消失改为置 deleted_time 墓碑而非硬删,复用 (source_id,channel_key)
身份原地复活恢复原 id,收藏/续播/health 跨刷新不丢;8 个读路径过滤墓碑。
迁移 0011 纯 ADD COLUMN,不动 FFI。同步更新 P0a 测试的版本号断言(10→11)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
lbb00 and others added 15 commits June 8, 2026 15:28
iOS Engine 持有 proxy_port,init_engine 启动 127.0.0.1 代理并返回端口;
新增 get_proxy_port 导出,RustBridge 存 proxyPort,对齐 android-tv。
注:Swift 侧因离线无法拉取 vlckit-spm 未能整体编译验证,改动类型安全且与 android 一致;Rust+udl 侧 cargo build 0 error。

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

新增 channel_groups + channel_group_links,频道可属多组;M3U group-title 按 ; 拆分,
channels.group_name 保留原始整串作 original_group;list_groups/list_channels 改走链表,
叠加墓碑过滤;墓碑保留 link、复活重建。迁移 0012。顺带把 p0a/p0b 迁移测试的全局版本
断言改为稳健形式(断言自身迁移已注册)。不动 FFI。

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

M3U(catchup/catchup-type/tvg-rec/catchup-source/catchup-days/timeshift) 与
Xtream(tv_archive/tv_archive_duration) 解析为频道级 catchup;保留原始 type/模板/days,
catchup-days×24 归一化为 catchup_hours(非法/缺失 NULL);upsert 双分支落库、revive 保留。
sources 加源级 catchup 列占位。迁移 0013。顺带把迁移测试的全局版本断言改稳健。不动 FFI。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
channels_fts(name) 与 epg_programs_fts(title,description) external-content FTS5,
trigram 分词保留中英文任意子串;查询词 <3 字符回退 LIKE(中文双字兜底);
搜索结果过滤墓碑频道(顺带修 search_programs 缺失的 deleted_time 过滤)。迁移 0014。不动 FFI。

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

M3U EXTVLCOPT/inline 解析 http-user-agent/http-referrer 并入库(迁移 0015);
PlaybackSourceDto 扩 13 字段(ua/referer/proxy_recommended/kind/priority/catchup_*/health/...);
resolve_playback 组装这些决策信息,并修复 get_enabled_by_id/list_playback_candidates
丢弃 catchup 的 bug。各端 FFI 未动(From 只读旧字段,照常编译)。

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

ios/android-tv/android-phone(UniFFI) + harmony-tv/phone(NAPI) 的 PlaybackInfo
struct/From/udl/Types.ets 同步 PlaybackSourceDto 的 13 个新字段(ua/referer/
proxy_recommended/kind/priority/catchup_*/health/...),全可选向后兼容。
消费侧未接线(新字段不读不崩)。

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

重生成 opentivi.swift 使 PlaybackInfo 反映 P0f 新增的 13 个字段,
解除 iOS 播放器重构对新字段不可见的阻塞。生成产物,勿手改。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…S1-S8) [UNVERIFIED]

双 backend 抽象(VideoPlayerBackend + AVPlayerBackend/VLCPlayerBackend),StreamPlayer 降级为
门面/切换器;ViewModel 走 resolvePlayback→decide 路由(mpegts→VLC, hls/native→AVPlayer);
AVURLAsset 注入 User-Agent/Referer(第一阶段不走代理);AVPlayer 失败回退 VLC(对 stall/候选透明);
Info.plist 加后台音频 + PiP(仅 AVPlayer)。

未编译验证:本环境离线(无 vlckit-spm/无法 xcodebuild)。待真机验收:
4 个新文件需在 Xcode 加入 OpenTivi target;HLS 子请求是否继承注入头;后台音频/PiP;
AVPlayer→VLC 回退无黑屏;resolvePlayback 返回的 kind 取值与 decide 匹配。

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

/stream 读 ua/referer query 并注入 4 处上游请求(GET/HEAD/加速分片/fallback);
playlist 缓存改用复合 key(url+ua+referer)防不同 header 串台;rewrite_m3u8 把
ua/referer 透传进重写后的子分片 URL(避免 HLS 分片丢头)。仅 UA/Referer 白名单,
SSRF 防护不变。不动 FFI。

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

export_backup: VACUUM INTO 一致快照(合并 WAL) + sha256 + zip(manifest.json+opentivi.db);
import_backup: 校验 format/schema 版本兼容 + 逐文件 sha256,全部通过才替换,旧库保留为
opentivi.db.bak-<时间>。新增 zip/sha2 依赖、DbExecutor::db_path、current_schema_version。
纯 core(平台文件选择/FFI 后续)。120 测试绿。

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

epg_reminders(channel_id FK CASCADE, program_start_epoch 稳定键, fired_at 防重触发,
UNIQUE(channel_id,start));add/remove/list/due/mark_fired;list/due JOIN channels+sources
过滤墓碑(deleted_time IS NULL)与禁用源;due 左闭右开窗口。迁移 0016。ReminderDto。
纯 core(平台通知/精确定时/FFI 后续)。127 测试绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
backup(export/import) + reminders(add/remove/list/due/mark_fired) 7 个 #[tauri::command]
接 core 服务并注册到 invoke_handler,桌面端可调用。前端 UI 后续。cargo build src-tauri 0 error。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ios/android-tv/android-phone(UniFFI) + harmony-tv/phone(NAPI) 暴露 export_backup/
import_backup + reminders 的 add/remove/list/due/mark_fired,附 ReminderInfo/
BackupManifestInfo/BackupFileInfo 镜像 struct + From。additive 向后兼容,消费侧UI后续。
3 个 uniffi rust crate host 0 error;harmony type-check 通过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
汇总本分支工作(P0 数据地基 0010-0014 / P0f 播放决策 0015 / iOS 选项2 /
P1 备份提醒 0016 / desktop commands / mobile FFI)、验证状态、待真机清单与 roadmap。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
与其余 app/core crate 的 Cargo.lock 保持一致(均已跟踪),harmony 两端补入库。

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

1 participant