Bring in symbols from other projects; new and open send the clock home
Dropping a symbol out of the pool's all-assets folder fetches that project's clip and the blocks it names, copies the symbol and everything it places in through clip/adopt — renamed where ids collide — and places it where it was dropped. It comes in as drawing: its tracking stays with the analysis that measured it. New and open now seek the audio clock to 0 with the readout, where play used to pick up wherever the last document's audio had got to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
490460bf45
commit
7bb80d315d
2 changed files with 62 additions and 1 deletions
|
|
@ -23,6 +23,8 @@
|
||||||
fx, which is the only thing in this namespace that is not pure."
|
fx, which is the only thing in this namespace that is not pure."
|
||||||
(:require [arthur.db :as db]
|
(:require [arthur.db :as db]
|
||||||
[arthur.domain.clip :as clip]
|
[arthur.domain.clip :as clip]
|
||||||
|
[arthur.domain.leaf :as leaf]
|
||||||
|
[arthur.events.edit :as edit]
|
||||||
[arthur.audio.mix :as mix]
|
[arthur.audio.mix :as mix]
|
||||||
[arthur.demo.stage :as stage]
|
[arthur.demo.stage :as stage]
|
||||||
[arthur.domain.feature :as feature]
|
[arthur.domain.feature :as feature]
|
||||||
|
|
@ -118,6 +120,58 @@
|
||||||
(-> (mix/mix! built (clip/opens-on built) (:audio entry) (:store entry))
|
(-> (mix/mix! built (clip/opens-on built) (:audio entry) (:store entry))
|
||||||
(.then (fn [audio] (assoc entry :audio audio)))))))))))
|
(.then (fn [audio] (assoc entry :audio audio)))))))))))
|
||||||
|
|
||||||
|
(defn- saved-clip!
|
||||||
|
"Promise of clip `cid` of saved project `pid`, as `{:clip :store}`: its
|
||||||
|
document and the blocks it names, and nothing played or mixed."
|
||||||
|
[pid cid]
|
||||||
|
(-> (http/GET (str "/api/projects/" pid))
|
||||||
|
(.then (fn [^js doc]
|
||||||
|
(let [^js c (or (first (filter #(= cid (.-cid ^js %)) (array-seq (.-clips doc))))
|
||||||
|
(throw (ex-info "that project no longer has that clip" {:cid cid})))]
|
||||||
|
(-> (js/Promise.all (into-array (map #(http/GET (str "/api/blocks/" %))
|
||||||
|
(array-seq (.-blocks c)))))
|
||||||
|
(.then (fn [blocks]
|
||||||
|
(project/load cid #js {:leaves (.-leaves c) :blocks blocks})))))))))
|
||||||
|
|
||||||
|
(rf/reg-fx
|
||||||
|
::import!
|
||||||
|
(fn [{:keys [project cid] :as request}]
|
||||||
|
(-> (saved-clip! project cid)
|
||||||
|
(.then #(rf/dispatch [::imported request %]))
|
||||||
|
(.catch (fn [error]
|
||||||
|
(js/console.error error)
|
||||||
|
(rf/dispatch [::failed (or (ex-message error) (str error))]))))))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
::import
|
||||||
|
;; A symbol out of another saved project, dropped at `frame` of the open symbol
|
||||||
|
;; and, from the stage, with its middle on `point`.
|
||||||
|
(fn [{:keys [db]} [_ carried frame point]]
|
||||||
|
{:db (update db :project merge {:status (str "fetching " (:label carried) "…")})
|
||||||
|
::import! (assoc (select-keys carried [:project :cid :symbol :label])
|
||||||
|
:host (get-in db [:ui :open]) :frame frame :point point)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
::imported
|
||||||
|
;; Copied, not linked: the symbol and everything it places come in under ids of
|
||||||
|
;; their own, with the blocks they name, and editing them here does not touch
|
||||||
|
;; the project they came from. They come in as DRAWINGS — their tracking stays
|
||||||
|
;; with the analysis that measured them — so they play but do not re-tune.
|
||||||
|
(fn [{:keys [db]} [_ {:keys [symbol host frame point label]} other]]
|
||||||
|
(let [sid (leaf/unsegment symbol)
|
||||||
|
uuid (random-uuid)
|
||||||
|
{:keys [clip ids]} (clip/adopt (:clip (store/entry (:clip/current db)))
|
||||||
|
(:clip other) [sid] {})
|
||||||
|
db (edit/edit-entry
|
||||||
|
db
|
||||||
|
#(let [st (merge (:store %) (:store other))]
|
||||||
|
(assoc % :store st
|
||||||
|
:clip (clip/place-symbol clip st host (ids sid) frame uuid point))))]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:ui :selection] [:node host uuid [uuid]])
|
||||||
|
(update :project merge {:status (str "brought in " label)}))
|
||||||
|
:dispatch [::pb/refresh-clock]})))
|
||||||
|
|
||||||
(rf/reg-fx
|
(rf/reg-fx
|
||||||
::save!
|
::save!
|
||||||
(fn [{:keys [id cid label clip]}]
|
(fn [{:keys [id cid label clip]}]
|
||||||
|
|
@ -424,6 +478,9 @@
|
||||||
(pb/show id)
|
(pb/show id)
|
||||||
(assoc :project {:id nil :cid (:cid entry) :name nil :seq nil
|
(assoc :project {:id nil :cid (:cid entry) :name nil :seq nil
|
||||||
:busy? false :status "new document"}))
|
:busy? false :status "new document"}))
|
||||||
|
;; The readout goes home with the document; so must the clock, or play
|
||||||
|
;; picks up wherever the last document's audio had got to.
|
||||||
|
::pb/seek! [(:fps entry) (clip/frames (:clip entry) (clip/opens-on (:clip entry))) 0]
|
||||||
::pb/pause! nil})))
|
::pb/pause! nil})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
|
@ -499,7 +556,9 @@
|
||||||
:cid (:cid (store/entry clip-id))
|
:cid (:cid (store/entry clip-id))
|
||||||
:busy? false
|
:busy? false
|
||||||
:status (str "opened " name " r" seq)}))
|
:status (str "opened " name " r" seq)}))
|
||||||
::pb/pause! nil}))
|
::pb/pause! nil
|
||||||
|
::pb/seek! (let [{c :clip fps :fps} (store/entry clip-id)]
|
||||||
|
[fps (clip/frames c (clip/opens-on c)) 0])}))
|
||||||
|
|
||||||
(rf/reg-event-db
|
(rf/reg-event-db
|
||||||
::failed
|
::failed
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
(:require [arthur.domain.clip :as clip]
|
(:require [arthur.domain.clip :as clip]
|
||||||
[arthur.domain.palette :as pal]
|
[arthur.domain.palette :as pal]
|
||||||
[arthur.events.footage :as footage]
|
[arthur.events.footage :as footage]
|
||||||
|
[arthur.events.project :as project]
|
||||||
[arthur.events.ui :as ui]
|
[arthur.events.ui :as ui]
|
||||||
[arthur.footage.store :as store]
|
[arthur.footage.store :as store]
|
||||||
[re-frame.core :as rf]))
|
[re-frame.core :as rf]))
|
||||||
|
|
@ -100,5 +101,6 @@
|
||||||
;; Video is asked about before anything happens: which frames, and what
|
;; Video is asked about before anything happens: which frames, and what
|
||||||
;; the symbol they become is called.
|
;; the symbol they become is called.
|
||||||
:footage (rf/dispatch [::footage/ask-convert c frame point])
|
:footage (rf/dispatch [::footage/ask-convert c frame point])
|
||||||
|
:import (rf/dispatch [::project/import c frame point])
|
||||||
nil))
|
nil))
|
||||||
(done!))
|
(done!))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue