chiark / gitweb /
bundles: Show in web UI
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 3 May 2021 17:10:45 +0000 (18:10 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 3 May 2021 17:10:45 +0000 (18:10 +0100)
Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
daemon/session.rs
nwtemplates/bundles-info-pane.tera [new file with mode: 0644]
src/bundles.rs
src/prelude.rs
src/updates.rs
templates/macros.tera
templates/script.ts

index 174e25f5645e205fc4d2bf9df10da10d1070deb6..b53c89766505febdc6bb8abf9dacb875b0274ffd 100644 (file)
@@ -23,6 +23,7 @@ struct SessionRenderContext {
   sse_url_prefix: String,
   links: Html,
   player_info_pane: Html,
+  bundles_info_pane: Html,
   fake_rng: bool,
 }
 
@@ -235,6 +236,7 @@ fn session_inner(form: Json<SessionForm>,
       nick,
       sse_url_prefix,
       player_info_pane,
+      bundles_info_pane: ig.bundle_list.info_pane()?,
       ptoken: form.ptoken.clone(),
       links: (&*ig.links).into(),
       fake_rng: config().game_rng.is_fake(),
diff --git a/nwtemplates/bundles-info-pane.tera b/nwtemplates/bundles-info-pane.tera
new file mode 100644 (file)
index 0000000..14361fe
--- /dev/null
@@ -0,0 +1,10 @@
+{# -*- HTML -*- -#}
+<!-- Copyright 2020-2021 Ian Jackson and contributors to Otter
+     SPDX-License-Identifier: AGPL-3.0-or-later
+     There is NO WARRANTY. -->
+{% for b in bundles %}
+<div class="bundle">
+<a href=""><code class="b_id">#{{ b.id }}</code></a>
+<span class="b_title">{{ b.title }}</span>
+</div>
+{% endfor %}
index bf066c9e73c0e5f8d068f227ec85f8174f46b0d4..1af062f4b8b8a4969614807662c0f335c8476d16 100644 (file)
@@ -42,6 +42,7 @@ impl FromStr for Index {
   #[throws(Self::Err)]
   fn from_str(s: &str) -> Index { Index(u16::from_str(s)?) }
 }
+hformat_as_display!{Id}
 
 const BUNDLES_MAX: Index = Index(64);
 
@@ -214,7 +215,18 @@ impl InstanceBundles {
   fn updated(&self, ig: &mut Instance) {
     ig.bundle_list = self.iter().map(|(id, state)| {
       (id, state.clone())
-    }).collect()
+    }).collect();
+
+    let new_info_pane = ig.bundle_list.info_pane().unwrap_or_else(|e|{
+      let m = "error rendering bundle list";
+      error!("{}: {}", m, e);
+      Html::from_txt(m)
+    });
+    let new_info_pane = Arc::new(new_info_pane);
+    let mut prepub = PrepareUpdatesBuffer::new(ig, Some(1));
+    prepub.raw_updates(vec![
+      PUE::UpdateBundles { new_info_pane }
+    ]);
   }
 
   #[throws(IE)]
@@ -291,6 +303,33 @@ impl Uploading {
   }
 }
 
+#[ext(pub)]
+impl MgmtBundleList {
+  #[throws(IE)]
+  fn info_pane(&self) -> Html {
+    #[derive(Serialize,Debug)]
+    struct RenderPane {
+      bundles: Vec<RenderBundle>,
+    }
+    #[derive(Serialize,Debug)]
+    struct RenderBundle {
+      id: Html,
+      title: Html,
+    }
+    let bundles = self.iter().filter_map(|(&id, state)| {
+      if_let!{ State::Loaded(Loaded { meta }) = state; else return None; }
+      let BundleMeta { title } = meta;
+      let id = hformat!("{}", id);
+      let title = Html::from_txt(title);
+      Some(RenderBundle { id, title })
+    }).collect();
+
+    Html::from_html_string(
+      nwtemplates::render("bundles-info-pane.tera", &RenderPane { bundles })?
+    )
+  }
+}
+
 impl InstanceBundles {
   #[throws(MgmtError)]
   pub fn finish_upload(&mut self, ig: &mut Instance,
index 177220af3c4a0e326389b0d1e36da90577e78f78..dce8bf08f3d8debe081183b43d230bd42eca0a51 100644 (file)
@@ -122,7 +122,7 @@ pub use crate::accounts::loaded_acl::{self, EffectiveACL, LoadedAcl, PermSet};
 pub use crate::accounts::*;
 pub use crate::authproofs::{self, Authorisation, Unauthorised};
 pub use crate::authproofs::AuthorisationSuperuser;
-pub use crate::bundles::{self, InstanceBundles};
+pub use crate::bundles::{self, InstanceBundles, MgmtBundleListExt};
 pub use crate::commands::{AccessTokenInfo, AccessTokenReport, MgmtError};
 pub use crate::commands::{MgmtCommand, MgmtResponse};
 pub use crate::commands::{MgmtGameInstruction, MgmtGameResponse};
index ebfb9373ea443408006f9747df769957d6b9ac58..53b69871562bbaed27e478020fd32272d8f012f7 100644 (file)
@@ -70,6 +70,9 @@ pub enum PreparedUpdateEntry {
     player: PlayerId,
     new_info_pane: Arc<Html>,
   },
+  UpdateBundles {
+    new_info_pane: Arc<Html>,
+  },
   Log(Arc<CommittedLogEntry>),
   Error(ErrorSignaledViaUpdate<PUE_P>),
 }
@@ -246,6 +249,9 @@ enum TransmitUpdateEntry<'u> {
     player: PlayerId,
     new_info_pane: &'u Html,
   },
+  UpdateBundles {
+    new_info_pane: &'u Arc<Html>,
+  },
   SetLinks(Html),
   #[serde(serialize_with="serialize_logentry")]
   Log(TransmitUpdateLogEntry<'u>),
@@ -438,6 +444,9 @@ impl PreparedUpdateEntry {
       RemovePlayer { player:_, new_info_pane } => {
         new_info_pane.json_len() + 100
       }
+      UpdateBundles { new_info_pane } => {
+        new_info_pane.json_len() + 100
+      }
       SetTableColour(colour) => {
         colour.json_len() + 50
       }
@@ -953,6 +962,9 @@ impl PreparedUpdate {
         &PUE::RemovePlayer { player, ref new_info_pane } => {
           TUE::RemovePlayer { player, new_info_pane }
         }
+        &PUE::UpdateBundles { ref new_info_pane } => {
+          TUE::UpdateBundles { new_info_pane }
+        }
         PUE::Error(e) => {
           match *e {
             ESVU::InternalError => TUE::Error(ESVU::InternalError),
index eaf65f49d69b646411959cefdf3ff34fce03b2e1..4ca17ce7fe6dafea84b82649f6db8e1606ae28ee 100644 (file)
@@ -110,6 +110,7 @@ Hi {{nick | escape}}
     <div class="uokey">Show
       <strong>H</strong> this help
       <strong>U</strong> players
+      <strong>B</strong> bundles
     </div>
   </div>
  </div>
@@ -123,6 +124,15 @@ Hi {{nick | escape}}
   </div>
  </div>
 
+ <div id="pane_bundles" class="somepane" style="display:none">
+  <div id="bundle_list_columns">
+<div><strong>Bundles</strong> (<strong>H</strong>/<strong>B</strong>: return to help)</div>
+  <div id="bundle_list">
+{{ bundles_info_pane }}
+  </div>
+  </div>
+ </div>
+
 </div id="infopane">
 {% endmacro infopane %}
 
index d5c9d309fe566c6c98faab2866002557bbaad8ac..4df5d069408f72a9f3e1630807b2dbc50e195487 100644 (file)
@@ -153,6 +153,7 @@ type PaneName = string;
 const pane_keys : { [key: string]: PaneName } = {
   "H" : "help",
   "U" : "players",
+  "B" : "bundles",
 };
 
 const uo_kind_prec : { [kind: string]: number } = {
@@ -1360,6 +1361,12 @@ function player_info_pane_set(j: PlayersUpdate) {
     .innerHTML = j.new_info_pane;
 }
 
+messages.UpdateBundles = <MessageHandler>function
+(j: { new_info_pane: string }) {
+  document.getElementById('bundle_list')!
+    .innerHTML = j.new_info_pane;
+}
+
 messages.SetTableSize = <MessageHandler>function
 ([x, y]: [number, number]) {
   function set_attrs(elem: Element, l: [string,string][]) {