diff --git a/tl/resources/public/css/app.css b/tl/resources/public/css/app.css index c165d4a..1817a2d 100644 --- a/tl/resources/public/css/app.css +++ b/tl/resources/public/css/app.css @@ -454,6 +454,20 @@ html.dark .timeline-head { .upload-pct { font-family: var(--mono); font-size: 11px; min-width: 36px; text-align: right; } /* editor: project bar above the timeline — a Mac window title bar (selected) */ +/* --- editor loading / error state -------------------------------------- */ +.editor-status { + flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; + background: var(--paper); color: var(--ink); font-family: var(--chicago); +} +.editor-status-msg { display: flex; align-items: center; gap: 10px; font-size: 14px; } +.editor-status-msg.err { color: #e66; } +.spinner { + width: 14px; height: 14px; border: 2px solid var(--ink); + border-top-color: transparent; border-radius: 50%; + animation: tl-spin .7s linear infinite; +} +@keyframes tl-spin { to { transform: rotate(360deg); } } + /* --- top bar: HyperCard window title bar -------------------------------- */ .titlebar { flex-shrink: 0; display: flex; align-items: center; gap: 8px; diff --git a/tl/src/tl/events.cljs b/tl/src/tl/events.cljs index 8fc7d7f..068c35a 100644 --- a/tl/src/tl/events.cljs +++ b/tl/src/tl/events.cljs @@ -126,19 +126,26 @@ (assoc db :auth {:authenticated false} :projects nil :net-error "Couldn't reach the server; logged out locally."))) +;; Drop everything the editor loaded for a project, so navigating away (or into +;; the next one) doesn't flash the previous project's name/scene/thumbnails or a +;; stale load error while the next one loads. +(defn- reset-project [db] + (merge db (select-keys db/default-db [:project :scene :fps :view :load :save-error]))) + (rf/reg-event-fx ::nav-list - (fn [{:keys [db]} _] {:db (assoc db :page :list) :fetch-projects true})) + (fn [{:keys [db]} _] {:db (-> (reset-project db) (assoc :page :list)) + :fetch-projects true})) (rf/reg-event-db ::set-projects (fn [db [_ ps]] (assoc db :projects ps :projects-error nil))) -(rf/reg-event-db ::nav-create (fn [db _] (assoc db :page :create :create-error nil))) +(rf/reg-event-db ::nav-create (fn [db _] (-> (reset-project db) + (assoc :page :create :create-error nil)))) ;; loading a project is a three-hop chain: detail → OTIO file → scene, each ;; feeding the next, and any hop's failure lands the editor in :error. (rf/reg-event-fx ::open-project (fn [{:keys [db]} [_ id view-state]] - {:db (-> db + {:db (-> (reset-project db) (assoc :page :editor) (assoc-in [:load :status] :loading) - (assoc-in [:load :error] nil) (assoc-in [:view :route-state] view-state)) :http-xhrio (api/GET (str "/api/projects/" id "/") {:on-success [::project-detail-loaded] diff --git a/tl/src/tl/views.cljs b/tl/src/tl/views.cljs index a4eaaaf..e9e4059 100644 --- a/tl/src/tl/views.cljs +++ b/tl/src/tl/views.cljs @@ -1091,7 +1091,8 @@ [:span.titlebar-status.err "thumbnails failed"])] [:div.titlebar-center [:a.title-back {:href (routes/href :projects) :title "Back to projects"} "‹"] - [:span.title-name (:name proj)]] + [:span.title-name (or (:name proj) + (when (= :loading @(rf/subscribe [::subs/status])) "Loading…"))]] [:div.titlebar-right [share-menu] (when authed? [user-menu])]])) @@ -1105,18 +1106,22 @@ linking? (some? @(rf/subscribe [::subs/linking]))] [:div.app {:class (str (when authoring? "picking ") (when linking? "linking"))} [top-bar] - [:div.top - [:div.video-pane [video-monitor] [frame-readout]] - [:div.annot-pane [annot-pane]]] - [:div.divider-h {:on-pointer-down drag-top!}] - [:div.timeline-pane - [breadcrumbs] - [toolbar] - [:div.timeline-scroll - (case status - :ready [timeline] - :error [:div {:style {:color "#e66" :padding 12}} (or load-err "Failed to load project")] - [:div {:style {:padding 12}} "Loading…"])]]])) + ;; only render the editor once the project is fully loaded — otherwise show a + ;; clean loading/error state rather than the previous project's panes. + (case status + :ready + [:<> + [:div.top + [:div.video-pane [video-monitor] [frame-readout]] + [:div.annot-pane [annot-pane]]] + [:div.divider-h {:on-pointer-down drag-top!}] + [:div.timeline-pane + [breadcrumbs] + [toolbar] + [:div.timeline-scroll [timeline]]]] + :error + [:div.editor-status [:div.editor-status-msg.err (or load-err "Failed to load project")]] + [:div.editor-status [:div.editor-status-msg [:span.spinner] "Loading…"]])])) ;; --- project list / create (the landing pages) ---------------------------