Streambert Watch History Tracking Implementation: A Technical Deep Dive
Streambert persists watch history using a structured localStorage schema that tracks playback progress, completed episodes, and chronological history through four specific keys managed by a centralized storage utility.
Streambert implements a lightweight yet robust watch history tracking system using the browser's localStorage API. The implementation centers around a key registry defined in src/utils/storage.js that coordinates data persistence across the Electron main and renderer processes. This architecture enables real-time progress updates, automatic "watched" status detection, and seamless backup functionality without external database dependencies.
Core Storage Schema and Architecture
The STORAGE_KEYS Registry
All watch-related data keys are centrally declared in src/utils/storage.js (lines 35-50) within the exported STORAGE_KEYS object. This registry prevents key collisions and provides a single source of truth for storage identifiers throughout the application.
// src/utils/storage.js – central key registry
export const STORAGE_KEYS = {
WATCH_PROGRESS: "progress",
WATCHED: "watched",
HISTORY: "history",
WATCHED_THRESHOLD: "watchedThreshold",
// …other unrelated keys
};
Data Structure Overview
The system utilizes four primary keys to maintain comprehensive watch state:
WATCH_PROGRESS("progress"): Stores the current playback position in seconds for the active episodeWATCHED("watched"): Maintains an object mapping episode IDs to booleantruevalues for completed contentHISTORY("history"): Contains a chronological array of episode IDs in reverse order (most recent first)WATCHED_THRESHOLD("watchedThreshold"): Defines the percentage (default 95%) of an episode that must be viewed to trigger automatic "watched" status
Real-Time Progress Tracking
IPC Communication Flow
When the video player reports a new playback position, the main process sends updates via the "update-progress" IPC channel. According to src/ipc/player.js, the main window emits progress events containing the current percentage and download status:
// src/ipc/player.js – update-progress handler (excerpt)
mw.webContents.send("update-progress", {
percent,
label: `Downloading… ${mb} MB ${totalMb}`,
});
The renderer-side listener in src/preload.js forwards these events to the UI layer, enabling the storage utility to persist positions using storage.set(STORAGE_KEYS.WATCH_PROGRESS, currentSeconds).
Automatic Watched Status Detection
When playback reaches the WATCHED_THRESHOLD (default 95% of total duration), Streambert automatically marks the episode as fully watched. The implementation updates both the WATCHED object and the HISTORY array:
// Mark as watched when threshold reached
storage.set(STORAGE_KEYS.WATCHED, {
...storage.get(STORAGE_KEYS.WATCHED),
[episodeId]: true,
});
// Update chronological history
const hist = storage.get(STORAGE_KEYS.HISTORY) || [];
hist.unshift(episodeId);
storage.set(STORAGE_KEYS.HISTORY, hist);
Managing Watch History Data
Retrieving Watch History
To display a "Recently Watched" list, UI components import the storage utility and retrieve the chronological history array. The most recent entries appear at the beginning of the array due to the unshift operation used during updates.
import { storage, STORAGE_KEYS } from "./utils/storage";
// Get the chronological watch history
const history = storage.get(STORAGE_KEYS.HISTORY) || [];
// Show the last 5 entries
history.slice(0, 5).forEach((episodeId) => {
console.log("Recently watched:", episodeId);
});
Manually Marking Episodes as Watched
Applications can programmatically mark content as watched using the same pattern as the automatic threshold detection:
import { storage, STORAGE_KEYS } from "./utils/storage";
function markAsWatched(episodeId) {
const watched = storage.get(STORAGE_KEYS.WATCHED) || {};
watched[episodeId] = true;
storage.set(STORAGE_KEYS.WATCHED, watched);
// Also add to history
const history = storage.get(STORAGE_KEYS.HISTORY) || [];
history.unshift(episodeId);
storage.set(STORAGE_KEYS.HISTORY, history);
}
Clearing and Resetting Watch Data
Streambert provides a complete data purge mechanism through the IPC handler clear-watch-data implemented in src/ipc/downloads.js at line 909. This handler iterates through all watch-related keys and removes them from localStorage:
ipcMain.handle("clear-watch-data", async () => {
for (const key of ["progress", "watched", "history", "watchedThreshold"]) {
storage.remove(key);
}
});
The frontend invokes this handler through the preload bridge exposed in src/preload.js:
// src/preload.js – expose clearWatchData to the renderer
clearWatchData: () => ipcRenderer.invoke("clear-watch-data"),
Settings UI components call window.electron.clearWatchData() when users request to clear their history:
// From a Settings component
window.electron.clearWatchData().then(() => {
alert("Watch history cleared!");
});
Backup and Restore Integration
Watch history survives application reinstalls through the backup system defined in src/utils/backup.js (lines 8-28). This file explicitly includes the watch-related keys—"watched", "progress", and "history"—in the exportable data set, ensuring user progress continuity across devices or application migrations. When users export their Streambert configuration, these keys serialize to JSON and restore cleanly on import.
Summary
- Centralized key registry:
src/utils/storage.jsdefinesSTORAGE_KEYSto maintain consistent localStorage identifiers for watch data - Real-time IPC updates: The
"update-progress"channel insrc/ipc/player.jscoordinates playback position tracking between main and renderer processes - Threshold-based completion: Episodes automatically mark as watched at 95% completion, updating both the watched set and chronological history
- Complete data management: The
clear-watch-datahandler insrc/ipc/downloads.jsprovides atomic deletion of all watch-related entries - Persistence across installs:
src/utils/backup.jsincludes watch data in export/import operations, ensuring state survival through reinstalls
Frequently Asked Questions
Where does Streambert store watch history data?
Streambert stores all watch history data in the browser's localStorage under specific keys defined in src/utils/storage.js. The data includes playback progress (seconds), watched episode IDs, chronological history arrays, and the completion threshold percentage. This design ensures data persistence without requiring external database infrastructure.
What percentage of an episode must be watched to mark it as complete?
By default, Streambert marks an episode as watched when the user reaches 95% of the total duration. This threshold is configurable via the WATCHED_THRESHOLD key in localStorage, allowing users or developers to adjust the completion criteria between 0-100%.
How can I programmatically clear watch history in Streambert?
Invoke the clear-watch-data IPC handler exposed through the Electron context bridge. The frontend calls window.electron.clearWatchData(), which triggers the handler in src/ipc/downloads.js to delete the "progress", "watched", "history", and "watchedThreshold" keys from localStorage, effectively resetting all watch-related data.
Is watch history included when backing up Streambert data?
Yes. The backup utility in src/utils/backup.js explicitly includes the watch-related keys ("watched", "progress", "history") in the export schema (lines 8-28). This ensures that when users export their settings and data, their watch progress and history serialize to the backup file and restore correctly on import.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →