T22: Collaboration
- presence: avatars ringed in each peer's color with where they are, press to follow; a breathing live dot; follow mode frames the view and stops on Escape - remote cursors and selections painted over a field from its own layout - comment threads with replies, reactions and resolve; a marker that opens a thread in a bubble; a sidebar of open and resolved threads - annotations washed in their authors' colors, notes on hover - suggestion mode: edits become suggestions word by word; track changes shows them struck and underlined, to accept or reject - sharing: invite by email with checked chips, roles, the access list and who the link lets in, in one dialog - primitives::hold_focus gives a mode its own focus, shared with ZenMode - AvatarGroup's tuck and count shared; Avatar::ring_color; TagInput::check; TextInput::bounds_for_range; Popover::size - icons: smile-plus, user-plus, message-square-diff - gallery: the Collaboration page with scripted states
This commit is contained in:
34 files changed
+3297
-86
No files matched your search
@@ -170,6 +170,46 @@ pub(crate) fn give_back(state: &Entity<Takeover>, window: &mut Window, cx: &mut
|
||||
}
|
||||
}
|
||||
|
||||
/// A mode's own focus, where focus was before the mode took it, and whether the mode was on last frame.
|
||||
pub(crate) struct Held {
|
||||
pub focus: FocusHandle,
|
||||
previous: Option<FocusHandle>,
|
||||
was_on: bool,
|
||||
}
|
||||
|
||||
/// The focus a mode keyed `key` holds: turned on while focus is elsewhere, it takes focus so Escape reaches it.
|
||||
pub(crate) fn hold_focus(
|
||||
key: impl Into<ElementId>,
|
||||
on: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Entity<Held> {
|
||||
let held = window.use_keyed_state(key, cx, |_, cx| Held {
|
||||
focus: cx.focus_handle(),
|
||||
previous: None,
|
||||
was_on: false,
|
||||
});
|
||||
let (focus, was_on) = (held.read(cx).focus.clone(), held.read(cx).was_on);
|
||||
if on && !was_on && !focus.contains_focused(window, cx) {
|
||||
log::info!("focus: a mode takes it, so Escape reaches it");
|
||||
let previous = window.focused(cx);
|
||||
window.focus(&focus);
|
||||
held.update(cx, |held, _| held.previous = previous);
|
||||
}
|
||||
if on != was_on {
|
||||
held.update(cx, |held, _| held.was_on = on);
|
||||
}
|
||||
held
|
||||
}
|
||||
|
||||
/// Hands focus back to where it was before the mode took it.
|
||||
pub(crate) fn hand_back(held: &Entity<Held>, window: &mut Window, cx: &mut App) {
|
||||
if let Some(previous) = held.update(cx, |held, _| held.previous.take()) {
|
||||
log::info!("focus: handed back after a mode");
|
||||
window.focus(&previous);
|
||||
}
|
||||
}
|
||||
|
||||
/// A focus handle kept for `id`, a Tab stop while enabled.
|
||||
pub(crate) fn tab_stop(
|
||||
id: ElementId,
|
||||
|
||||
Reference in new issue
Block a user