Skip to content

mlathrom/mr-timecode

Repository files navigation

Mr. Timecode

A spreadsheet for working with sequences of SMPTE timecode. Edit timecodes like cells in Excel, copy/paste between this and your spreadsheet of choice, and use cascade mode to re-time a sequence by shifting every subsequent cell by the same delta.

Features

  • Spreadsheet-style grid with cell selection, arrow/Tab/Enter navigation, undo/redo, and clipboard copy/paste (TSV).
  • Frame rates: 23.976, 24, 25, 29.97, 30, 50, 59.94, 60. Drop-frame supported on 29.97 and 59.94 with proper SMPTE math.
  • View toggle: switch between timecode (HH:MM:SS:FF / HH:MM:SS;FF) and raw frame counts. Underlying data is always stored as integer frames, so frame-rate switches are lossless.
  • Cascade mode (Off / Column / Row): when you edit a cell, every subsequent cell in the same column or row shifts by the same delta. One undo reverts the entire cascade.
  • Lenient parsing: input accepts any mix of : and ; separators (00:00:01:00, 00:00:01;00, 00;00;01;00 all work). Output is canonical for the current rate.
  • Paste-to-grow: pasting a range that overflows the grid auto-extends rows and columns.
  • Add row / Add column buttons at the grid edges.
  • CSV export in either timecode or frames format (RFC 4180 quoting, \r\n line endings).
  • Autosaves to localStorage — your grid, frame rate, view mode, and cascade mode survive page reloads.
  • No font/color/formatting controls — focused on timecode work.

Tech stack

  • Vue 3 (Composition API, <script setup> SFCs)
  • TypeScript (strict)
  • Vite 8
  • Tailwind CSS v4
  • Vitest

Running locally

npm install
npm run dev      # http://localhost:5173
npm test         # timecode unit tests (drop-frame round-trips etc.)
npm run build    # production bundle in dist/

Vite 8 wants Node 20.19+ or 22.12+. Older versions may still work but emit warnings.

Renaming the app

The display name lives in a single constant — change it in src/config.ts:

export const APP_NAME = 'Mr. Timecode';

The browser tab title, the header label, and the CSV export filename all read from APP_NAME. No other code identifiers reference the name.

Project structure

src/
├── main.ts                # entry, hydrates state and mounts Vue app
├── App.vue                # toolbar + grid layout
├── config.ts              # APP_NAME, defaults, supported frame rates
├── types.ts               # FrameRate, ViewMode, CascadeMode, Cell, Grid
├── timecode/
│   ├── timecode.ts        # parse/format, NDF + DF math
│   └── timecode.test.ts   # unit tests
├── store/
│   ├── grid.ts            # cells, dims, edit/paste/range ops
│   ├── settings.ts        # frame rate, view mode, cascade mode
│   ├── history.ts         # undo/redo snapshot stack
│   └── persistence.ts     # localStorage hydrate + autosave
├── components/
│   ├── Toolbar.vue        # frame rate / DF toggle / view / cascade / export
│   ├── Grid.vue           # table render, selection, keyboard nav, paste
│   └── Cell.vue           # editable cell
├── composables/
│   ├── useCascade.ts      # apply delta to downstream cells
│   ├── useClipboard.ts    # copy/cut/paste handlers
│   └── useCsvExport.ts    # build CSV blob, trigger download
└── styles.css

Keyboard shortcuts

Key Action
Move selection
Tab / Shift+Tab Move right / left
Enter Start edit, or commit and move down
Shift+Enter Commit and move up (in editor)
Esc Cancel edit
F2 Start edit on selected cell
Delete / Backspace Clear selected cells
Ctrl/Cmd+C / Ctrl/Cmd+X / Ctrl/Cmd+V Copy / Cut / Paste (TSV)
Ctrl/Cmd+Z Undo
Ctrl/Cmd+Y / Ctrl/Cmd+Shift+Z Redo

License

MIT

About

Timecode spreadsheet

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages