From 6b20a958f4e8db5614fffb27fe5d32f07ddfe855 Mon Sep 17 00:00:00 2001 From: Aram Drevekenin Date: Tue, 6 Feb 2024 14:26:14 +0100 Subject: feat(sessions): welcome screen (#3112) * prototype - can send layout name for new session from session-manager * feat(sessions): ui for selecting layout for new session in the session-manager * fix: send available layouts to plugins * make tests compile * fix tests * improve ui * fix: respect built-in layouts * ui for built-in layouts * some cleanups * style(fmt): rustfmt * welcome screen ui * fix: make sure layout config is not shared between sessions * allow disconnecting other users from current session and killing other sessions * fix: respect default layout * add welcome screen layout * tests(plugins): new api methods * fix(session-manager): do not quit welcome screen on esc and break * fix(plugins): adjust permissions * style(fmt): rustfmt * style(fmt): fix warnings --- zellij-utils/src/plugin_api/event.proto | 6 +++ zellij-utils/src/plugin_api/event.rs | 57 +++++++++++++++++++++--- zellij-utils/src/plugin_api/plugin_command.proto | 8 ++++ zellij-utils/src/plugin_api/plugin_command.rs | 30 +++++++++++-- 4 files changed, 92 insertions(+), 9 deletions(-) (limited to 'zellij-utils/src/plugin_api') diff --git a/zellij-utils/src/plugin_api/event.proto b/zellij-utils/src/plugin_api/event.proto index 0d964a354..e26a9c23a 100644 --- a/zellij-utils/src/plugin_api/event.proto +++ b/zellij-utils/src/plugin_api/event.proto @@ -152,6 +152,12 @@ message SessionManifest { repeated PaneManifest panes = 3; uint32 connected_clients = 4; bool is_current_session = 5; + repeated LayoutInfo available_layouts = 6; +} + +message LayoutInfo { + string name = 1; + string source = 2; } message ResurrectableSession { diff --git a/zellij-utils/src/plugin_api/event.rs b/zellij-utils/src/plugin_api/event.rs index d9e5341d6..21ff1eff1 100644 --- a/zellij-utils/src/plugin_api/event.rs +++ b/zellij-utils/src/plugin_api/event.rs @@ -4,9 +4,9 @@ pub use super::generated_api::api::{ event::Payload as ProtobufEventPayload, CopyDestination as ProtobufCopyDestination, Event as ProtobufEvent, EventNameList as ProtobufEventNameList, EventType as ProtobufEventType, InputModeKeybinds as ProtobufInputModeKeybinds, - KeyBind as ProtobufKeyBind, ModeUpdatePayload as ProtobufModeUpdatePayload, - PaneInfo as ProtobufPaneInfo, PaneManifest as ProtobufPaneManifest, - ResurrectableSession as ProtobufResurrectableSession, + KeyBind as ProtobufKeyBind, LayoutInfo as ProtobufLayoutInfo, + ModeUpdatePayload as ProtobufModeUpdatePayload, PaneInfo as ProtobufPaneInfo, + PaneManifest as ProtobufPaneManifest, ResurrectableSession as ProtobufResurrectableSession, SessionManifest as ProtobufSessionManifest, TabInfo as ProtobufTabInfo, *, }, input_mode::InputMode as ProtobufInputMode, @@ -14,8 +14,8 @@ pub use super::generated_api::api::{ style::Style as ProtobufStyle, }; use crate::data::{ - CopyDestination, Event, EventType, InputMode, Key, ModeInfo, Mouse, PaneInfo, PaneManifest, - PermissionStatus, PluginCapabilities, SessionInfo, Style, TabInfo, + CopyDestination, Event, EventType, InputMode, Key, LayoutInfo, ModeInfo, Mouse, PaneInfo, + PaneManifest, PermissionStatus, PluginCapabilities, SessionInfo, Style, TabInfo, }; use crate::errors::prelude::*; @@ -453,6 +453,11 @@ impl TryFrom for ProtobufSessionManifest { .collect(), connected_clients: session_info.connected_clients as u32, is_current_session: session_info.is_current_session, + available_layouts: session_info + .available_layouts + .into_iter() + .filter_map(|l| ProtobufLayoutInfo::try_from(l).ok()) + .collect(), }) } } @@ -485,10 +490,42 @@ impl TryFrom for SessionInfo { panes, connected_clients: protobuf_session_manifest.connected_clients as usize, is_current_session: protobuf_session_manifest.is_current_session, + available_layouts: protobuf_session_manifest + .available_layouts + .into_iter() + .filter_map(|l| LayoutInfo::try_from(l).ok()) + .collect(), }) } } +impl TryFrom for ProtobufLayoutInfo { + type Error = &'static str; + fn try_from(layout_info: LayoutInfo) -> Result { + match layout_info { + LayoutInfo::File(name) => Ok(ProtobufLayoutInfo { + source: "file".to_owned(), + name, + }), + LayoutInfo::BuiltIn(name) => Ok(ProtobufLayoutInfo { + source: "built-in".to_owned(), + name, + }), + } + } +} + +impl TryFrom for LayoutInfo { + type Error = &'static str; + fn try_from(protobuf_layout_info: ProtobufLayoutInfo) -> Result { + match protobuf_layout_info.source.as_str() { + "file" => Ok(LayoutInfo::File(protobuf_layout_info.name)), + "built-in" => Ok(LayoutInfo::BuiltIn(protobuf_layout_info.name)), + _ => Err("Unknown source for layout"), + } + } +} + impl TryFrom for ProtobufCopyDestination { type Error = &'static str; fn try_from(copy_destination: CopyDestination) -> Result { @@ -1383,6 +1420,11 @@ fn serialize_session_update_event_with_non_default_values() { panes: PaneManifest { panes }, connected_clients: 2, is_current_session: true, + available_layouts: vec![ + LayoutInfo::File("layout 1".to_owned()), + LayoutInfo::BuiltIn("layout2".to_owned()), + LayoutInfo::File("layout3".to_owned()), + ], }; let session_info_2 = SessionInfo { name: "session 2".to_owned(), @@ -1392,6 +1434,11 @@ fn serialize_session_update_event_with_non_default_values() { }, connected_clients: 0, is_current_session: false, + available_layouts: vec![ + LayoutInfo::File("layout 1".to_owned()), + LayoutInfo::BuiltIn("layout2".to_owned()), + LayoutInfo::File("layout3".to_owned()), + ], }; let session_infos = vec![session_info_1, session_info_2]; let resurrectable_sessions = vec![]; diff --git a/zellij-utils/src/plugin_api/plugin_command.proto b/zellij-utils/src/plugin_api/plugin_command.proto index 6ffb0345b..b02dd73f7 100644 --- a/zellij-utils/src/plugin_api/plugin_command.proto +++ b/zellij-utils/src/plugin_api/plugin_command.proto @@ -91,6 +91,8 @@ enum CommandName { BlockCliPipeInput = 77; CliPipeOutput = 78; MessageToPlugin = 79; + DisconnectOtherClients = 80; + KillSessions = 81; } message PluginCommand { @@ -145,9 +147,14 @@ message PluginCommand { string block_cli_pipe_input_payload = 48; CliPipeOutputPayload cli_pipe_output_payload = 49; MessageToPluginPayload message_to_plugin_payload = 50; + KillSessionsPayload kill_sessions_payload = 60; } } +message KillSessionsPayload { + repeated string session_names = 1; +} + message CliPipeOutputPayload { string pipe_name = 1; string output = 2; @@ -185,6 +192,7 @@ message SwitchSessionPayload { optional uint32 tab_position = 2; optional uint32 pane_id = 3; optional bool pane_id_is_plugin = 4; + optional event.LayoutInfo layout = 5; } message RequestPluginPermissionPayload { diff --git a/zellij-utils/src/plugin_api/plugin_command.rs b/zellij-utils/src/plugin_api/plugin_command.rs index fa570a267..a5272d426 100644 --- a/zellij-utils/src/plugin_api/plugin_command.rs +++ b/zellij-utils/src/plugin_api/plugin_command.rs @@ -4,10 +4,10 @@ pub use super::generated_api::api::{ input_mode::InputMode as ProtobufInputMode, plugin_command::{ plugin_command::Payload, CliPipeOutputPayload, CommandName, ContextItem, EnvVariable, - ExecCmdPayload, HttpVerb as ProtobufHttpVerb, IdAndNewName, MessageToPluginPayload, - MovePayload, NewPluginArgs as ProtobufNewPluginArgs, OpenCommandPanePayload, - OpenFilePayload, PaneId as ProtobufPaneId, PaneType as ProtobufPaneType, - PluginCommand as ProtobufPluginCommand, PluginMessagePayload, + ExecCmdPayload, HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, + MessageToPluginPayload, MovePayload, NewPluginArgs as ProtobufNewPluginArgs, + OpenCommandPanePayload, OpenFilePayload, PaneId as ProtobufPaneId, + PaneType as ProtobufPaneType, PluginCommand as ProtobufPluginCommand, PluginMessagePayload, RequestPluginPermissionPayload, ResizePayload, RunCommandPayload, SetTimeoutPayload, SubscribePayload, SwitchSessionPayload, SwitchTabToPayload, UnsubscribePayload, WebRequestPayload, @@ -574,6 +574,7 @@ impl TryFrom for PluginCommand { name: payload.name, tab_position: payload.tab_position.map(|p| p as usize), pane_id, + layout: payload.layout.and_then(|l| l.try_into().ok()), })) }, _ => Err("Mismatched payload for SwitchSession"), @@ -727,6 +728,16 @@ impl TryFrom for PluginCommand { }), })) }, + _ => Err("Mismatched payload for MessageToPlugin"), + }, + Some(CommandName::DisconnectOtherClients) => match protobuf_plugin_command.payload { + None => Ok(PluginCommand::DisconnectOtherClients), + _ => Err("Mismatched payload for DisconnectOtherClients"), + }, + Some(CommandName::KillSessions) => match protobuf_plugin_command.payload { + Some(Payload::KillSessionsPayload(KillSessionsPayload { session_names })) => { + Ok(PluginCommand::KillSessions(session_names)) + }, _ => Err("Mismatched payload for PipeOutput"), }, None => Err("Unrecognized plugin command"), @@ -1082,6 +1093,7 @@ impl TryFrom for ProtobufPluginCommand { tab_position: switch_to_session.tab_position.map(|t| t as u32), pane_id: switch_to_session.pane_id.map(|p| p.0), pane_id_is_plugin: switch_to_session.pane_id.map(|p| p.1), + layout: switch_to_session.layout.and_then(|l| l.try_into().ok()), })), }), PluginCommand::OpenTerminalInPlace(cwd) => Ok(ProtobufPluginCommand { @@ -1205,6 +1217,16 @@ impl TryFrom for ProtobufPluginCommand { })), }) }, + PluginCommand::DisconnectOtherClients => Ok(ProtobufPluginCommand { + name: CommandName::DisconnectOtherClients as i32, + payload: None, + }), + PluginCommand::KillSessions(session_names) => Ok(ProtobufPluginCommand { + name: CommandName::KillSessions as i32, + payload: Some(Payload::KillSessionsPayload(KillSessionsPayload { + session_names, + })), + }), } } } -- cgit v1.2.3