Skip to content

feat: full frontend - inline player, UI overhaul, recording UI, perf fixes#397

Closed
wowitsjack wants to merge 2 commits intoFredolx:mainfrom
wowitsjack:contrib/2-frontend
Closed

feat: full frontend - inline player, UI overhaul, recording UI, perf fixes#397
wowitsjack wants to merge 2 commits intoFredolx:mainfrom
wowitsjack:contrib/2-frontend

Conversation

@wowitsjack
Copy link

Summary

Complete frontend overhaul building on #396 (backend). Adds inline player, full UI redesign, recording UI, and performance optimizations.

Inline Player

  • HLS.js web engine and embedded MPV engine selection
  • Native <video> element with VA-API hardware decode
  • Local MPEG-TS proxy integration for non-HLS streams
  • Player state management (closed/minimized/expanded)

UI Overhaul

  • Sidebar navigation with collapsible state
  • Dashboard with content rows (history, favorites, categories)
  • Channel cards with lazy-loaded images
  • Channel detail panel (slide-in)
  • Now-playing bar
  • Search overlay (Ctrl+K)
  • View density toggle (grid large/small, list)
  • CSS custom properties design system
  • Restyled EPG modal, download manager, settings

Recording UI

  • Record button in channel tile context menu
  • Active recording state display
  • Recording service with start/stop management

Performance

  • ChangeDetectionStrategy.OnPush on channel cards
  • loading="lazy" decoding="async" on images
  • Removed backdrop-filter: blur() (WebKitGTK CPU killer)
  • Removed infinite box-shadow animation
  • Dashboard limited to 80 max cards (was 264)

Settings

  • Player engine selection (Web/MPV/External MPV)
  • User agent, proxy, connection timeout
  • EPG and source auto-refresh intervals
  • Buffer size
  • Backup export/import (replace all or merge)

Part 2 of 2 - Depends on #396 for backend.

Test plan

  • Dashboard loads with history, favorites, category rows
  • Inline player plays HLS and MPEG-TS streams
  • Sidebar navigation works, collapse persists
  • Search overlay finds channels
  • Recording starts/stops from context menu
  • Settings save and persist
  • Idle CPU stays under 25% on dashboard

@CLAassistant
Copy link

CLAassistant commented Mar 7, 2026

CLA assistant check
All committers have signed the CLA.

…, local player

Centralized HTTP client (http.rs) with proxy, user-agent, timeout.
Server-side recording system (recording.rs) with active recording
management. Background scheduler (scheduler.rs) for EPG and source
auto-refresh. Full database backup/restore (backup.rs). Local MPEG-TS
proxy (local_player.rs) with ffmpeg + warp for stream transcoding,
HEAD-request URL resolution, and broadcast-based lifecycle. All new
settings fields, commands, and exit cleanup wired in lib.rs.
…fixes

Inline player with HLS.js web engine and embedded MPV support.
Complete UI overhaul: sidebar navigation, dashboard with content rows,
channel cards, detail panel, now-playing bar, search overlay, view
density toggle. Recording UI in channel tiles. CSS design system with
custom properties. Performance: OnPush change detection, lazy images,
no backdrop-filter blur, reduced dashboard card count. All new
settings (networking, scheduler, backup/restore, player engine).
Updated README, screenshot, and app metadata.
@wowitsjack wowitsjack force-pushed the contrib/2-frontend branch from e01ccf4 to 60485d6 Compare March 7, 2026 17:32
@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

Way too many changes in a single PR, this smells like AI vibecode, sorry.

@Fredolx Fredolx closed this Mar 11, 2026
@wowitsjack
This comment was marked as a violation of GitHub Acceptable Use Policies
@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

Way too many changes in a single PR, this smells like AI vibecode, sorry.

How do I unsponsor your project? What a dickhead reply. lmao.

It is vibecoded, you literally have a .claude added to the gitignore.

@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

I would be glad to work together and have your contributions as long as you make them yourself, having AI code in this codebase can be legally dubious.

@wowitsjack
Copy link
Author

wowitsjack commented Mar 11, 2026

It is vibecoded, you literally have a .claude added to the gitignore.

The .claude directory is created automatically by the Claude Code extension in VS Code. Adding it to .gitignore is standard practice, the same way you'd gitignore .vscode or .idea. It doesn't mean every line of code was AI-generated.

I would be glad to work together and have your contributions as long as you make them yourself, having AI code in this codebase can be legally dubious.

I use AI tooling the same way I use autocomplete, documentation, and Stack Overflow: as part of the development process, not a replacement for understanding the code. Every feature in this PR was designed, tested, and debugged by me. The .claude directory being in .gitignore isn't evidence of anything.

That said, it's your project and your call. I respect that. I'll be taking my work in a different direction as an independent project. No hard feelings on the technical disagreement, we just have different philosophies on how software gets built in 2026.

@wowitsjack
Copy link
Author

wowitsjack commented Mar 11, 2026

Since I'll be forking independently and doing a clean rewrite, I want to set clear IP boundaries for the unmerged work in this PR and #396:

I hereby prohibit you, Frédéric Lachapelle, along with the entire FredTV project from using, deriving from, or copying any of the code, or design of my contributions.

You can consider this a formal legal notice, and I am absolutely willing to exercise my legal options should you do so.

To be clear: this applies only to the unmerged contributions in these PRs which you chose to reject. Your existing codebase is entirely yours. I'll be doing a clean rewrite with zero shared code.

@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

I hereby prohibit you, Frédéric Lachapelle, along with the entire FredTV project from using, deriving from, or copying any of the code, or design of my contributions.

You can consider this a formal legal notice, and I am absolutely willing to exercise my legal options should you do so.

Unfortunately, this is not how open source works and I can sue you if you decide to relicense your fork of my project.

@wowitsjack
Copy link
Author

wowitsjack commented Mar 11, 2026

Unfortunately, this is not how open source works and I can sue you if you decide to relicense your fork of my project.

I have no intention of relicensing your code. The plan is a clean rewrite from scratch, not a relicense. Different codebase, no shared code, independent implementation.

Threatening to sue a contributor is a choice, though. Especially one who set a boundary around code you explicitly rejected and never merged.

@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

Ok, have fun with Claude 😂

@wowitsjack
Copy link
Author

wowitsjack commented Mar 11, 2026

Ok, have fun with Claude 😂

The inline player, the recording system, the HLS proxy, the sidebar navigation, the design system. Those are real features solving real user problems.

Dismissing it all with "have fun with Claude" after zero code review is exactly the attitude that made me decide to fork. The app can't even embed video playback inline, it shells out to an external mpv window. That's the core limitation these PRs were addressing. Brother I was cleaning up your frankly embarrassing code.

Your project, your standards. I wish you well with it.

@Fredolx
Copy link
Owner

Fredolx commented Mar 11, 2026

My code is open source, you are free to fork and modify it as you wish as long as you respect the license. Having people fork my projects and vibecode new features to them is par with the course when it comes to open source nowadays, unfortunately. Have a nice day.

@JoshNewbury
Copy link

JoshNewbury commented Mar 11, 2026

This was hilarious, thanks for rejecting the AI slop, absolutely embarrassing comments from wowitsjack

@cvsouth
Copy link

cvsouth commented Mar 11, 2026

@wowitsjack You are definitely the more unhinged one in this scenario. 10 points to Griffindor.

@vexxvakan
Copy link

@wowitsjack lmfao massive cringe, imagine being this slow thinking 😂

@CollinLaurentStone
Copy link

No wonder @wowitsjack is unemployed 😆

@antoinefortin
Copy link

That was funny

@NeurekaSoftware
Copy link

@wowitsjack I don’t think I’ve seen anything so unhinged on GitHub before. Slow claps my guy, congratulations on looking like a total weirdo. 🫠

@fardavide
Copy link

fardavide commented Mar 11, 2026

Damn, AI is coming for our jobs!

edit: sorry wrong chat

@janhkrueger
Copy link

@Fredolx is absolutely right in rejecting any PRs which does not fit the owners standards. Not your project, not your decision.
No matter how big or small a PR, no matter if hand written or with ai assistance.

@wowitsjack keep in mind that the mindset you show is not advocating to hire you at any position. If you can't deal with criticism or (code) rejection and than crashing out that way you are not fitting in any team. Such, public viewable, behavior is a simple no go.

@JulienLavocat
Copy link

@Fredolx you should probably limit who can talk on this PR, I know it's possible but I don't know how 😅

As much as I agree with other people here about the author of this PR, there is no need to keep saying it.

@Dich0tomy
Copy link

New Entitled AI-Powered Di***ts, now with even more audacity! Have them shoved down your throat right now! ✨

@bogosj
Copy link

bogosj commented Mar 11, 2026

To all of the people commenting on @wowitsjack 's completely unhinged behavior - your life will be a lot better if you block people and move on.

https://github.com/wowitsjack
Scroll down, bottom of the left column. Block, and write yourself a note referencing this PR.

@JolanUK
Copy link

JolanUK commented Mar 11, 2026

I don’t have any interest in jumping on the bandwagon, I just want to offer my support towards the most recent comment about blocking Jack. This PR seems to have become rather popular on Reddit and, if you’re here due to that, please just have a bit of a think if you’re in this PR for the right reasons or if you’re here to dogpile on someone you have already decided deserves it.

As someone that’s crashed out in a spectacular way like this in the past, publicly too and in a similarly humiliating fashion, I’d suggest that there could be any number of issues going on that made a very calm and kind dismissal of their PR into quite a spiteful and negative experience. Autism, RSD, loneliness, a need to ‘belong’, absolutely any formative experience with someone that’s turned hearing ‘no’ into a threat, especially in a situation like this where the PR was as likely for friendship or social approval as it was for genuinely improving the project.

If you’ve decided to judge Jack before walking a mile in his shoes, don’t be surprised if he has blisters you don’t know about. You really don’t need to insult him today.

@bogosj
Copy link

bogosj commented Mar 11, 2026

@JolanUK - I appreciate the perspective you've shared here. You’re right that we don’t always know the internal or external battles someone is fighting, and I apologize for repeating the word "unhinged". It was a poor choice of words for a potentially complicated situation.

However, I want to reiterate my main point: no one is inherently owed another person's time or attention, especially when they become abusive. Whatever personal struggles someone may be facing, they do not serve as an excuse to mistreat or harass others. The recommendation to block is not about "dogpiling". It is a tool for individuals to protect themselves from potential future aggressive or abusive behavior. Open source thrives on collaboration, but that collaboration has to be built on a foundation of mutual respect.

@JolanUK
Copy link

JolanUK commented Mar 11, 2026

@JolanUK - I appreciate the perspective you've shared here. You’re right that we don’t always know the internal or external battles someone is fighting, and I apologize for repeating the word "unhinged". It was a poor choice of words for a potentially complicated situation.

However, I want to reiterate my main point: no one is inherently owed another person's time or attention, especially when they become abusive. Whatever personal struggles someone may be facing, they do not serve as an excuse to mistreat or harass others. The recommendation to block is not about "dogpiling". It is a tool for individuals to protect themselves from potential future aggressive or abusive behavior. Open source thrives on collaboration, but that collaboration has to be built on a foundation of mutual respect.

Ah, I may have caused myself to be misunderstood.

I didn't in any way aim to suggest you were dogpiling in particular - you weren't. I was referencing the comments belittling the guy for having an objectively quite humiliating experience. There's no way around how irredeemably awful this was - whether it's today, tomorrow, next week or when he has a moment that really puts his behaviour on this PR into perspective, he'll know what he did and it'll hurt. The comments calling him a weirdo or belittling his approach won't help with that, they'll just start to teach him that his own individual struggles shouldn't be viewed with compassion and support but instead mocked on sight.

There are a lot of you that had the opportunity to help him to rehabilitate his skillset and attitude (Laracasts is right there, CBT is right there, Spotify is awash with behavioural psychology audiobooks) but didn't and I hope you'll think about that the next time one of these threads hits Reddit. Someone you know or care about might be the person in it.

@CodeStation5
Copy link

Assuming its not vibe coded, what makes you think its ok to modify 95 files in a single PR?

@cvsouth
Copy link

cvsouth commented Mar 11, 2026

@JolanUK Hey, I'm gonna respectfully push back on that a little bit.

His behaviour was insulting and threatening and I don't think people should get a pass for that just in case maybe they have mental health issues or something. This is a technical space on the internet, not somewhere that participation awards are given out.

Where I think the line should be drawn is to only attack people in terms of the work and contribution itself and never personal or ad hominem. You have been the main one to make it personal by bringing his mental health into question. Calling out his unhinged crashout as being unhinged is simply calling a spade a spade.

I do appreciate your sentiment of bringing the human element into the equation though and I think that's important, just in this specific case I am pushing back against that argument.

@JolanUK
Copy link

JolanUK commented Mar 11, 2026

@JolanUK Hey, I'm gonna respectfully push back on that a little bit.

His behaviour was insulting and threatening and I don't think people should not get a pass for that just in case maybe they have mental health issues or something. This is a technical space on the internet, not somewhere that participation awards are given out.

Where I think the line should be drawn is to only attack people in terms of the work and contribution itself and never personal or ad hominem. You have been the main one to make it personal by bringing his mental health into question. Calling out his unhinged crashout as being unhinged is simply calling a spade a spade.

I do appreciate your sentiment of bringing the human element into the equation though and I think that's important, just in this specific case I am pushing back against that argument.

Fair. Can't argue with that, and I wouldn't dream of giving off the impression the creator of this PR should be coddled. If it helps to reinforce anything, I've asked Github to get involved because Jack shouldn't get away with how he's acted here (both technically, and behaviourally). I'm firmly on the side of rehabilitation though, not tiptoeing but more importantly, certainly not shaming and I think the two issues should be separated. Jack should quite rightly feel a deep sense of regret for how he's acted, but should also be readily supported in turning that around.

I appreciate the comment about divorcing the human aspect, and that perhaps I was unfair in psychoanalysing the guy but when you've made enough of one mistake, you grow the superpower to be able to pick up on when others are doing it too. I don't see a healthy person writing the comments I've seen from him here, and I'd be happy to challenge anyone that does.

@cvsouth
Copy link

cvsouth commented Mar 11, 2026

Fair. Can't argue with that, and I wouldn't dream of giving off the impression the creator of this PR should be coddled. If it helps to reinforce anything, I've asked Github to get involved because Jack shouldn't get away with how he's acted here (both technically, and behaviourally). I'm firmly on the side of rehabilitation though, not tiptoeing but more importantly, certainly not shaming and I think the two issues should be separated. Jack should quite rightly feel a deep sense of regret for how he's acted, but should also be readily supported in turning that around.

I appreciate the comment about divorcing the human aspect, and that perhaps I was unfair in psychoanalysing the guy but when you've made enough of one mistake, you grow the superpower to be able to pick up on when others are doing it too. I don't see a healthy person writing the comments I've seen from him here, and I'd be happy to challenge anyone that does.

I agree for the most part, although I don't think it matters from our perspective whether he is mentally unwell or not, I don't think we should be speculating on that. Although I'm definitely not stuck on that opinion and could certainly hear an argument that would change my mind.

It could also just have easily been me in his position. I like to think much less likely these days, but certainly when I had less hard won experience. The difference between being passionate and being overly emotional is an ultra thin line.

If I were to offer advice to Jack at this point it would be to swallow your pride and admit that you acted inappropriately. The community should respect and embrace that and anyone who doesn't should have the same level of shaming applied against them.

In my opinion Jack owes Fredolx an apology and that's all. The rest of it is water under the bridge.

@JolanUK
Copy link

JolanUK commented Mar 12, 2026

Fair. Can't argue with that, and I wouldn't dream of giving off the impression the creator of this PR should be coddled. If it helps to reinforce anything, I've asked Github to get involved because Jack shouldn't get away with how he's acted here (both technically, and behaviourally). I'm firmly on the side of rehabilitation though, not tiptoeing but more importantly, certainly not shaming and I think the two issues should be separated. Jack should quite rightly feel a deep sense of regret for how he's acted, but should also be readily supported in turning that around.
I appreciate the comment about divorcing the human aspect, and that perhaps I was unfair in psychoanalysing the guy but when you've made enough of one mistake, you grow the superpower to be able to pick up on when others are doing it too. I don't see a healthy person writing the comments I've seen from him here, and I'd be happy to challenge anyone that does.

I agree for the most part, although I don't think it matters from our perspective whether he is mentally unwell or not, I don't think we should be speculating on that. Although I'm definitely not stuck on that opinion and could certainly hear an argument that would change my mind.

It could also just of easily been have been me in his position. I like to think much less likely these days, but certainly when I had less hard won experience. Add ADHD and burnout to the list. The difference between being passionate and being overly emotional is an ultra thin line.

If I were to offer advice to Jack at this point it would be to swallow your pride and admit that you acted inappropriately. The community should respect and embrace that and anyone who doesn't should have the same level of shaming applied against them.

In my opinion Jack owes Fredolx an apology and that's all. The rest of it is water under the bridge.

I get that. I don't know if this is really the place (I'd wager it's not), but I believed in it enough to state it in a place where I'm trying to (re)build my career. We're not just seeing a flagrant disregard for development etiquette and a quite unpleasant streak (it's obvious and we all see it), we're watching a lack of self-preservation and an immediate, quite visceral impulsiveness that's causing him to torch his reputation over what looks on the surface to be the most minor slight (which I'm guaranteeing isn't minor to him). There's so much nuance to what's been said here, it's nowhere near as simple as 'this guy's rude, he's mentally ill' and I just want to share that for the avoidance of doubt. I think that can risk minimising mental health in quite a harmful way and that's not who I am. I know what's happening here, it's screaming at me.

That said, absolutely needs to swallow his pride, apologise to Fred and move on because Fred matters too and shouldn't have had to experience any of this today. In a way, it'd be quite a shame if that didn't happen.

As a side note, glad things are going better for you these days ❤️

@sambartik
Copy link

sambartik commented Mar 12, 2026

Since I'll be forking independently and doing a clean rewrite, I want to set clear IP boundaries for the unmerged work in this PR and #396:

I hereby prohibit you, Frédéric Lachapelle, along with the entire FredTV project from using, deriving from, or copying any of the code, or design of my contributions.

You can consider this a formal legal notice, and I am absolutely willing to exercise my legal options should you do so.

Just to clarify, you can not.

Under Github's ToS, by submitting this PR you license that content under the same terms, and you agree that you have the right to license that content under those terms. That grant was established at the time of submission.

And because opensource licenses are irrevocable, once the code has been contributed and licensed under these terms, the grant cannot be withdrawn. So the project as well as public retains the right to use, modify, and distribute the submitted code in accordance with the GPL-2.0 license.

And by the way, anyone can see the code, it does not matter you deleted your fork:

git clone https://github.com/Fredolx/open-tv.git
cd open-tv
git fetch origin pull/397/head:pr-397
git checkout pr-397

@gbrennon
Copy link

wtf?!

that user did expect this would be approved?

roflmao

@PixieXD
Copy link

PixieXD commented Mar 12, 2026

wowitsslop!

Having .claude on your gitignore is already suspicious enough. Even if no AI was used and jack was telling the truth, isn't 90+ file changes in a PR a bit too much..?

@baudneo
Copy link

baudneo commented Mar 12, 2026

@wowitsjack youre a clown buddy, go hop in your vibed out clown car with the 35 million other vibesloppers and fuc* all the way off. Honk honk 🤡🤡🤡

@antoinefortin
Copy link

I have nothing to do with this PR, but damn I love it! Keep them flowing

@tomal02
Copy link

tomal02 commented Mar 12, 2026

Damn, the edits are unhinged. Absolutely the worst way to have handled this.

@cacticrown
Copy link

i was here :D

@mufarodev
Copy link

we just have different philosophies on how software gets built in 2026.

found the Theo fan

@ThePrimeagen
Copy link

Since I'll be forking independently and doing a clean rewrite, I want to set clear IP boundaries for the unmerged work in this PR and #396:

I hereby prohibit you, Frédéric Lachapelle, along with the entire FredTV project from using, deriving from, or copying any of the code, or design of my contributions.

You can consider this a formal legal notice, and I am absolutely willing to exercise my legal options should you do so.

To be clear: this applies only to the unmerged contributions in these PRs which you chose to reject. Your existing codebase is entirely yours. I'll be doing a clean rewrite with zero shared code.

I would strongly recommend not going to Claude for legal advice

@HauberDevs
Copy link

HauberDevs commented Mar 12, 2026

@wowitsjack imagine being such a ding dong, the fact you refuse to even acknowledge you did use AI and then threaten the creator with frivolous legal action...

like dude you cant claim code as yours you didnt make yourself...

@sangoi-exe
Copy link

sangoi-exe commented Mar 12, 2026

Ok. Since the short version was deleted (sangoi did it), here is the autopsy report instead of the postcard.

First: not everything here is bad.

What is actually good:

  • Splitting backup.rs, http.rs, local_player.rs, recording.rs, and scheduler.rs out of src-tauri/src/lib.rs is directionally correct. This repo needed seams more than it needed another 500-line god file.
  • The settings surface is at least trying to expose real operational behavior instead of hiding everything behind folklore.
  • recording.rs at least attempts a graceful ffmpeg shutdown by sending q before escalating to kill. That is the correct instinct for MP4 finalization.
  • The UI rewrite is trying to become a product, not just a pile of forms and tiles. I can see the intended direction.

Now the part where intent collides with the code.

1. This is still too much PR for one body bag

This review unit is 95 files / +8770 -861 / 2 commits.
And those 2 commits are basically:

  • backend foundations
  • full frontend overhaul

So this PR combines backend lifecycle, playback plumbing, recording, scheduler behavior, backup/import/export, shell/navigation changes, dashboard/search/sidebar changes, settings redesign, lockfile churn, and CSS churn.

That is not “one feature”. That is several integration boundaries pretending to be roommates.

The irony is that README.md already describes this work as split across stacked PRs, but the actual review artifact here collapses a large chunk of that into one blast radius.

2. Tooling is broken before we even get to runtime

This is the easy blocker because it fails loudly and does not require philosophy.

corepack pnpm install --frozen-lockfile --ignore-scripts
fails with ERR_PNPM_OUTDATED_LOCKFILE.

Why?

  • pnpm-lock.yaml contains root hls.js
  • package.json does not

So the declared pnpm path is not reproducible in frozen mode.

That is not cosmetic. That is the repo telling reviewers “please inspect runtime behavior” while the dependency contract is already lying.

3. Playback contracts drift depending on which path the user hits

This is where the PR starts getting educational in the wrong way.

3.1 Embedded MPV (Inline) is wired into a state machine that does not support it

Multiple entrypoints route both PlayerEngine.Web and PlayerEngine.EmbeddedMpv into the inline-player flow:

  • channel-tile.component.ts
  • channel-detail-panel.component.ts
  • epg-modal-item.component.ts

But InlinePlayerComponent only boots playback when the engine is exactly PlayerEngine.Web.

So Embedded MPV (Inline) can push the app into expanded now-playing state without actually attaching a player.

That is a clean example of a feature existing in the selector, in the routing logic, and in the UI state machine, but not in the actual implementation.

3.2 buffer_size is a dead knob

The PR adds buffer_size end-to-end in:

  • TS settings model
  • Angular settings UI
  • Rust settings/types persistence

And then never consumes it in the inline player path.

So the user gets a shiny playback control that does exactly what all fake controls do: nothing.

3.3 local_player.rs has unsafe process ownership

On Unix, start_local_stream() runs:

pkill -9 -f "ffmpeg.*-f mpegts.*pipe:1"

That is not scoped to this app instance.
That is not scoped to an owned PID.
That is not scoped to a cache marker.
That is just a broad-spectrum host-level “I hope nothing else important matches this regex” cleanup strategy.

So starting inline playback can kill unrelated ffmpeg jobs on the machine.

That is an astonishingly bad ownership model.

3.4 The same startup path can leak ffmpeg on local bind failure

local_player.rs spawns ffmpeg before binding the local Warp server.
If the bind to 127.0.0.1:9321 fails, the function can return early and leave the child behind.

So the code manages to be both too aggressive when killing processes and not aggressive enough when cleaning up its own leaked child.
That is almost art.

3.5 UA behavior drifts across playback/fetch paths

The UI contract in source-tile.component.html says:

  • user_agent is for fetching/refreshing playlists
  • stream_user_agent is for playing streams

But http.rs lets channel requests fall back from stream_user_agent to user_agent.
Meanwhile MPV/recording paths preserve the split.

So stream behavior now depends on which internal path is doing the request.
That is contract drift, not implementation detail.

4. Recording is half-right and half-self-sabotage

4.1 The stop toggle is self-canceling on tile/detail flows

recording.service.ts does this:

  • toggleRecording() marks the channel busy first
  • on the stop path it calls stopRecording()
  • stopRecording() immediately returns if the same channel is already busy

So from tile/detail flows, the stop invoke never happens.

Meaning:

  • start recording works
  • stop recording from the same surface does nothing
  • the dedicated bar stop path still works

So the user gets different behavior depending on which button they press for the same action. Always a confidence builder.

5. Backup/import has real correctness problems, not just polish debt

This area deserves more scrutiny than it got.

5.1 Backup export silently drops row errors

In backup.rs, multiple exports do:

  • query_map(...)
  • then .filter_map(|r| r.ok())

That means row-level decode/schema failures are silently discarded while export still succeeds.

That is how you manufacture a backup file that looks valid and is quietly incomplete.

5.2 Merge import does not restore all the data it advertises

The backup payload includes:

  • channel_http_headers
  • epg_watchlist

import_replace() restores them.
import_merge() does not.

So merge mode can happily accept a backup that contains those sections and then silently drop them on the floor.

For IPTV data, losing channel_http_headers is not a cute little omission. That can directly break streams that need custom headers.

5.3 Merge duplicate logic for channels is too weak

import_merge() de-duplicates channels on (name, source_id).
That is not a safe identity for this data model.
It will collapse distinct rows that merely share a name in the same source.

So even where merge tries to be helpful, it is doing so with the subtlety of a hammer.

6. The shell/navigation rewrite also ships broken state ownership

6.1 Sidebar collapse double-toggles itself

The child component emits toggleCollapse and also mutates MemoryService directly.
The parent handles the emit and mutates MemoryService again.

One click, two toggles, zero reliable state change.

This is such a classic shared-state ownership mistake that it should be framed and hung in the hallway.

6.2 Browse filters can persist when the UI hides the fact that they persisted

Sidebar items like Movies set a media-type filter.
Items like Favorites, History, and Categories do not provide a replacement filter.
home.component.ts only rewrites filters.media_types when a new filter is present; otherwise it just hides the media-filter UI.

So you can do something like:

  • Movies
  • Favorites

and keep the movie-only filter while the controls that would reveal that fact are hidden.

That is hidden state, which is one of the fastest ways to make users think the app is haunted.

6.3 default_view loses to the dashboard default

The shell hard-defaults to dashboard/home state, while default_view still loads into filters later.
The result is that the new shell can override the persisted browse-mode expectation on first render.

If you expose a default-view setting and then route everyone to dashboard anyway, the setting is no longer a setting. It is fan fiction.

7. Scheduler/settings contracts are sloppier than the UI suggests

7.1 “EPG refresh interval” and “Source refresh interval” both call refresh_all()

The settings UI presents these as distinct schedules.
The scheduler implementation does not.
Both timer paths call the same full refresh.

So the UI is selling two knobs for one behavior.
If the user enables both, they are effectively scheduling duplicate heavy work.

7.2 Scheduler restart can race the async settings write

The settings UI does updateSettings(); restartScheduler() back-to-back.
updateSettings() is async.
restart_scheduler immediately reloads settings from storage.

So the restart can read stale values while the UI already shows the new ones.

That is not a theoretical nit. That is a real causal chain in the current code.

8. So what should happen instead?

If this work is real and should land, split it into reviewable units:

  • lockfile / package-manager / docs hygiene
  • backend process ownership and lifecycle
  • inline player contract
  • recording + scheduler + backup/import-export
  • shell/navigation/dashboard/search/UI/CSS

Because right now the code is trying to collect credit for modularization, product ambition, playback expansion, recording, scheduling, backup, and a visual redesign all at once.

And to be fair, the ambition is visible.
The problem is that the contracts are visible too.

This PR is not failing because it is ambitious.
It is failing because it tries to cash all the ambition in one place before the seams are trustworthy.

@morkev
Copy link

morkev commented Mar 13, 2026

Holy slop, man. Why not just fork the repo at that point. I think part of writing good software is in the modularity and keeping the system as loosely coupled as possible. If maintainers have to go through an 8k line PR just to figure out what you changed, that’s not a contribution, it’s just bad practice and an immediate rejection.

@itsnicksia
Copy link

My cat's name is Mittens

@awdev1
Copy link

awdev1 commented Mar 14, 2026

Besides the Scott Shambough story with the OpenClaw Agent, this is ridiculous and probably one of the craziest non automated GitHub crash outs I’ve seen.

@AntonyOnScript
Copy link

haha

@MarzHater
Copy link

Comedy gold, brightened my morning a bit.
Kudos to the guy who made the detailed analysis though, very good breakdown.

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.