/// /// import { declared, property, subclass } from "esri/core/accessorSupport/decorators"; import Accessor = require("esri/core/Accessor"); import HandleRegistry = require("esri/core/Handles"); import promiseUtils = require("esri/core/promiseUtils"); import watchUtils = require("esri/core/watchUtils"); import Collection = require("esri/core/Collection"); import SlideItem = require("./SlideItem"); import SceneView = require("esri/views/SceneView"); const SlideItemCollection = Collection.ofType(SlideItem); type State = "ready" | "loading" | "disabled"; @subclass("app.SlidesViewModel") class SlidesViewModel extends declared(Accessor) { //-------------------------------------------------------------------------- // // Lifecycle // //-------------------------------------------------------------------------- initialize() { this._handles.add( watchUtils.init(this, "view", view => this._viewUpdated(view)) ); } destroy() { this._handles.destroy(); this._handles = null; this.view = null; this.bookmarkItems.removeAll(); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- private _handles: HandleRegistry = new HandleRegistry(); //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // bookmarkItems //---------------------------------- @property({ type: SlideItemCollection }) bookmarkItems: Collection = new SlideItemCollection; //---------------------------------- // state //---------------------------------- @property({ dependsOn: ["view.ready"], readOnly: true }) get state(): State { const view = this.get("view"); const ready = this.get("view.ready"); return ready ? "ready" : view ? "loading" : "disabled"; } //---------------------------------- // view //---------------------------------- @property() view: SceneView = null; //-------------------------------------------------------------------------- // // Public Methods // //-------------------------------------------------------------------------- async goTo(bookmarkItem: SlideItem) { const { view } = this; if (!bookmarkItem) { return promiseUtils.reject(new Error("BookmarkItem is required")); } if (!view) { return promiseUtils.reject(new Error("View is required")); } bookmarkItem.active = true; const slide = bookmarkItem.slide; try { const applied = await slide.applyTo(view); bookmarkItem.active = false; return; } catch (error) { bookmarkItem.active = false; return; } } //-------------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------------- private _viewUpdated(view: SceneView): void { const { _handles } = this; const mapHandleKey = "map"; _handles.remove(mapHandleKey); if (!view) { return; } view.when(() => { _handles.add( watchUtils.init(view, "map", map => this._mapUpdated(<__esri.WebScene>map)) , mapHandleKey); }); } private _mapUpdated(map: __esri.WebScene): void { if (!map) { return; } const { bookmarkItems } = this; bookmarkItems.removeAll(); const slides = map.presentation.slides; slides.forEach((slide) => { bookmarkItems.add(new SlideItem({ slide, name: slide.title.text })) }); } } export = SlidesViewModel;