Skip to content

filmopen_recorder

Generated by scripts/package_digest.py; regenerate, never edit.

The issue recorder (Software Specification §6.8). While Recorder.instance records, every tap, drag, scroll, key, typed text, draft change, navigation, tab, route, setting and log event goes into tape.jsonl, with a JPEG of the whole view after each action, into a report folder beside the app’s logs (reportsDirectory(): on Windows %LOCALAPPDATA%\FilmOpen\reports\<YYMMDDHHMMSS>\). The folder also holds environment.json, the project’s text files as they were at the start (project/) and at the stop (project-after/), the library’s (library/) and the app log of this run and the one before, whole (log.jsonl, copyLogRuns, the runs named in environment.json’s logRuns). While it records the log is verbose (AppLog.forceVerbose), the setting untouched. On the web the tape is kept in memory and nothing is written.

Flutter. 8 files, 1,468 lines under lib/; 45 tests in 7 files. Barrel: lib/filmopen_recorder.dart.

  • filmopen_format — uses Entity
  • filmopen_store — uses AppLog, LogEntry, LogSink
  • filmopen_platform — uses reportsDirectory
  • filmopen_state — uses AutomationHost, BrowserState, DraftObserver, DraftObservers, FieldRegistry, LifecycleHook, NavIndex, OpenDrafts, RouteChange, RouteEvent, RouteEvents, RouteListener, SemanticsHit, Settings, browserProvider, builtMoment, currentTab, describeControl, findById, focusedTextIdentifier, isDictationCaption, isLiveDictationControl, localizationsProvider, navIndexProvider, projectProvider, selectionToJson, semanticsNodeAt, semanticsOwnerOf, settingsProvider, settleFrames and 2 more
  • filmopen_test_support (dev) — uses nothing by name the digest could see

Third-party: flutter_riverpod, image.

filmopen_app, filmopen_automation, filmopen_support

What the barrel exports, file by file. A name is class, enum, mixin, extension, typedef, a top-level function, getter, setter or variable; under a class, its public constructors, fields, getters, setters and methods.

  • typedef typedef ShotCapture — Paints the whole view and answers it as JPEG bytes, or null when nothing can be painted.
  • class Recorder — The issue recorder (§6.8): while it records, every action goes into a tape, with a picture of the whole view after each, into a report folder beside the app’s logs.
    • Recorder({ Future<ReportFolder> Function()? openFolder, bool? writesFiles, this._capture, Future<void> Function()? settle, this.valueDelay = const…
    • static Recorder instance — The recorder the app’s rail and the agent layer’s ops share.
    • final ValueNotifier<bool> recording — Whether a recording runs; the rail’s button listens to it.
    • final ValueNotifier<bool> busy — Whether a recording is starting or stopping — the open drafts, the folder, the snapshot — so a button can wait rather than be pressed twice.
    • ValueListenable<int> get shots — How many pictures this recording has written: zero at [start], raised once a picture’s bytes and its shot line are written, so that whoever listens acts after the capture — the flash that tells the person a picture…
    • final Duration valueDelay — How long after the last key the boxes are read for what was typed.
    • final double dragDistance — How far, in logical pixels, a pointer moves before a click is a drag.
    • final Duration draftsLimit — The longest [start] and [stop] wait for the open drafts to be written.
    • PictureSize get pictures — How this recording’s pictures are made.
    • bool get isRecording
    • String? get folder — The report folder’s path while recording, or of the last recording; null for one kept in memory.
    • ReportFolder? get lastFolder — The last recording’s folder, kept after [stop] (null in memory).
    • int get events — How many events the tape holds.
    • int get elapsedMilliseconds — The tape’s clock while a recording runs — what a line’s t says, so that a commentary’s lines and the tape’s share one clock — and zero while nothing records.
    • bool get lastStopFailed — Whether the last [stop] failed after giving the doors back (its folder may lack project-after/ or log.jsonl); recorder.failed says why.
    • Future<bool> start(ProviderContainer container, { String? appVersion, String? build, String? commit, String? builtAt, PictureSize pictures = const… — Starts a recording of the app [container] runs.
    • Future<String?> stop({String reason = 'stopped'}) — Ends the recording: reads the boxes a last time, waits for the last picture and the open drafts, gives back every door, writes stop, the project’s files as they are now and the log’s tail.
    • Future<void> get idle — Waits for the picture and the state after the last action.
  • function Future<List<int>?> captureWindowJpeg({double? pixelRatio, int quality = 90}) — The whole view ([AutomationHost.windowKey]) painted at [pixelRatio] — the view’s own where null — as JPEG of [quality] (§3.2).
  • class PictureSize — How a recording’s pictures are made: how many pixels each logical pixel of the view gets, and the JPEG’s quality.
    • const PictureSize({this.pixelRatio, this.quality = 90})
    • final double? pixelRatio — Pixels per logical pixel; null for the view’s own ratio, which is the screen’s pixels.
    • final int quality — The JPEG’s quality, 1 to 100.
    • static const PictureSize person — A person’s recording: the view’s logical size at quality 80, so that a long recording travels light, far under the 300 MB a support server takes.
  • function String reportWord(String value, {required String fallback, int max = 64}) — [value] where it is a word a report and a support ticket carry as it is, else [fallback].
  • class ReportFolder — The files of one recording.
    • String? get path — The folder’s path on disk; null for a recording kept in memory.
    • void appendLine(String relativePath, String line) — Appends [line] and a newline to the file at [relativePath].
    • void writeText(String relativePath, String text) — Writes [text] as the whole file at [relativePath].
    • void writeBytes(String relativePath, List<int> bytes) — Writes [bytes] as the whole file at [relativePath].
    • void appendBytes(String relativePath, List<int> bytes) — Appends [bytes] to the file at [relativePath]: the log, copied a chunk at a time.
  • class LogRuns — What a report’s log.jsonl holds of the app log (§6.8): the starts it begins at, what was copied, and where this run’s own lines begin in it.
    • const LogRuns({ required this.starts, required this.lines, required this.bytes, required this.files, required this.thisRunFrom, required this.incom…
    • static const LogRuns none — Nothing copied: no log file.
    • final List<Map<String, Object?>> starts — Each app.started the copy holds, oldest first: its time and the app’s version.
    • final int lines — How many lines were copied.
    • final int bytes — How many bytes were copied.
    • final int files — From how many of the log’s files.
    • final int thisRunFrom — The byte of log.jsonl where this run’s own app.started begins; 0 where it holds this run alone.
    • final bool incomplete — Whether fewer runs than asked were found: the start before this one rotated away, or there was none.
    • Map<String, Object?> toJson() — As environment.json names it, under logRuns.
  • class MemoryReportFolder — A recording kept in memory: the web build’s, where nothing is written, and the tests’.
    • final Map<String, String> texts — Every text file, by its path.
    • final Map<String, List<int>> binaries — Every binary file, by its path.
    • List<Map<String, Object?>> get tape — The tape’s lines as JSON objects.
  • function bool isReportPath(String relativePath) — Whether [relativePath] stays inside a report folder: not absolute, no drive, no backslash, no colon, no empty segment, . or ...
  • function void checkReportPath(String relativePath) — Refuses a path that could leave the report folder ([isReportPath]).
  • function String reportStamp(DateTime at) — A recording’s folder name for the moment [at], YYMMDDHHMMSS in local time (§3.3); openReportFolderIn adds -2, -3 for a second recording in the same second.
  • function bool isReportStamp(String stamp) — Whether [stamp] is a report folder’s name ([reportStamp]).
  • function DateTime? stampTime(String stamp) — When a folder was made, from its [stamp], or null where it is not one.
  • function String reportFolderName(String path) — The last segment of a report folder’s [path], its stamp: what the log and a receipt name it by, never the path, which holds the person’s user name on Windows (§6.8).
  • class DirectoryReportFolder — A folder on disk: not here, where nothing is written.
    • DirectoryReportFolder(this.path)
  • variable const bool hasReportFolders — Whether recordings are written to disk here: not on the web.
  • function Future<ReportFolder> openReportFolder({DateTime? now}) — Not available: a recording here is kept in memory.
  • function String operatingSystemVersion()
  • function String? userHomeDirectory() — No home here: the web has no paths of the person’s.
  • function Future<LogRuns> copyLogRuns(String? path, void Function(List<int> bytes) append, {int runs = 2}) — No log file here.
  • function Future<List<int>?> encodeJpeg(int width, int height, Uint8List rgba, {int quality = 90}) — No JPEG here: the web build writes no screenshot.
  • function ReportFolder openReportFolderIn(String parent, {DateTime? now}) — Not available: a recording here is kept in memory.
  • variable const Set<String> kSnapshotExtensions — The extensions of the text files a snapshot copies (§3.3): the project’s JSON and the text beside it, never media.
  • function bool isSnapshotPath(String path) — Whether [path] names a text file a snapshot copies.
  • function Future<int> snapshotSource(ProjectSource source, ReportFolder folder, String prefix) — Copies every text file of [source] into [folder] under [prefix] (project, project-after, library), as it is, and answers how many were copied.
  • variable const String kTapeFile — The tape’s file in a report folder.
  • class TapeWriter — Appends one JSON object per tape event, leaving completed lines readable after a crash (§6.8).
    • TapeWriter(this.folder, {DateTime Function()? clock, Stopwatch? watch})
    • final ReportFolder folder
    • int get elapsedMilliseconds — The tape’s clock: milliseconds since its first line, what every line’s t says.
    • int get events — How many lines are written.
    • int? write(String kind, [Map<String, Object?> fields = const {}]) — Writes an event of [kind] with [fields]; answers its seq, or null when the event was refused.
  • function bool isValueIdentifier(Object? id) — Whether [id] is an identifier under which a typed value travels into the tape.
  • variable const String kDictationIdentifiers — Shared dictation’s identifiers, whose text never travels as taped text (Software Specification §9.6).
  • function String utcMillis(DateTime time) — [time] in UTC as RFC 3339 with milliseconds: 2026-09-15T10:04:05.123Z.

Files under lib/ the barrel does not reach; nothing outside the package may import them.

  • lib/src/report_folder_io.dart: hasReportFolders, DirectoryReportFolder, openReportFolder, openReportFolderIn, operatingSystemVersion, userHomeDirectory, copyLogRuns, _eachChunk, _startLine, _startBytes, _mentionsStart, encodeJpeg