feat: add marketing video mode and Remotion marketing video project
Add debug-only Marketing Video Mode toggle that enables hands-free screen recording across the app: auto-scrolling Featured Trips carousel, auto-filling trip wizard, smooth trip detail scrolling via CADisplayLink, and trip options auto-sort with scroll. Add Remotion marketing video project with 6 scene compositions using image sequences extracted from screen recordings, varied phone entrance animations, and deduped frames for smooth playback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -511,6 +511,45 @@ final class ItineraryTableViewController: UITableViewController {
|
||||
ItineraryReorderingLogic.travelRow(in: flatItems, forDay: day)
|
||||
}
|
||||
|
||||
// MARK: - Marketing Video Auto-Scroll
|
||||
|
||||
#if DEBUG
|
||||
private var displayLink: CADisplayLink?
|
||||
private var scrollStartTime: CFTimeInterval = 0
|
||||
private var scrollDuration: CFTimeInterval = 6.0
|
||||
private var scrollStartOffset: CGFloat = 0
|
||||
private var scrollEndOffset: CGFloat = 0
|
||||
|
||||
func scrollToBottomAnimated(delay: TimeInterval = 1.5, duration: TimeInterval = 6.0) {
|
||||
guard UserDefaults.standard.bool(forKey: "marketingVideoMode") else { return }
|
||||
self.scrollDuration = duration
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self] in
|
||||
guard let self else { return }
|
||||
let maxOffset = self.tableView.contentSize.height - self.tableView.bounds.height + self.tableView.contentInset.bottom
|
||||
guard maxOffset > 0 else { return }
|
||||
self.scrollStartOffset = self.tableView.contentOffset.y
|
||||
self.scrollEndOffset = maxOffset
|
||||
self.scrollStartTime = CACurrentMediaTime()
|
||||
let link = CADisplayLink(target: self, selector: #selector(self.marketingScrollTick))
|
||||
link.add(to: .main, forMode: .common)
|
||||
self.displayLink = link
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func marketingScrollTick() {
|
||||
let elapsed = CACurrentMediaTime() - scrollStartTime
|
||||
let t = min(elapsed / scrollDuration, 1.0)
|
||||
// Ease-in-out curve
|
||||
let eased = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
|
||||
let newOffset = scrollStartOffset + (scrollEndOffset - scrollStartOffset) * eased
|
||||
tableView.contentOffset = CGPoint(x: 0, y: newOffset)
|
||||
if t >= 1.0 {
|
||||
displayLink?.invalidate()
|
||||
displayLink = nil
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// MARK: - Drag State Management
|
||||
//
|
||||
// These methods handle the start, update, and end of drag operations,
|
||||
|
||||
Reference in New Issue
Block a user