feat: party knock asks an invite-only party's host for an invite
party list already shows invite-only parties; knock closes the loop. The knocker can't run any tmux command against the server, so the channel is write(1), the same one invite uses toward guests, except here delivery failure is surfaced: the ping is the whole feature.
This commit is contained in:
parent
7770289d85
commit
6799a57405
5 changed files with 163 additions and 4 deletions
65
party
65
party
|
|
@ -55,6 +55,7 @@ Joining:
|
|||
--passive lands in the host's session (mirrored view).
|
||||
Read-only invitees always join passive.
|
||||
leave Detach from the party you joined.
|
||||
knock [name] Ask an invite-only party's host for an invite.
|
||||
role [active|passive|switch]
|
||||
Flip your clients between guest session and host session.
|
||||
|
||||
|
|
@ -1099,6 +1100,69 @@ cmd_leave() {
|
|||
|
||||
[ "$found" -gt 0 ] || { echo "party: not joined to any party." >&2; exit 1; }
|
||||
}
|
||||
|
||||
# Send the knock ping. Factored out of cmd_knock so the write(1)
|
||||
# interaction is testable: the CLI path to it needs a party hosted by
|
||||
# a DIFFERENT user, and roster trust anchors on dir ownership, which a
|
||||
# single-uid test run cannot fake.
|
||||
knock_send() {
|
||||
write "$1" 2>/dev/null <<EOF
|
||||
$USER wants to join '$2'.
|
||||
Run: party invite $USER --party $2
|
||||
EOF
|
||||
}
|
||||
|
||||
cmd_knock() {
|
||||
name=
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
cat <<'EOF'
|
||||
Usage: party knock [name]
|
||||
Ask a party's host for an invite. For parties `party list` shows as
|
||||
invite-only: you share the group, you're just not on the allowlist.
|
||||
The host gets a write(1) ping naming you and the invite command.
|
||||
EOF
|
||||
exit 0 ;;
|
||||
-*) echo "party knock: unknown flag '$1'" >&2; exit 2 ;;
|
||||
*)
|
||||
if [ -z "$name" ]; then name="$1"; shift
|
||||
else echo "party knock: unexpected arg '$1'" >&2; exit 2; fi
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$name" ]; then
|
||||
find_party_by_name "$name" && rc=0 || rc=$?
|
||||
case $rc in
|
||||
0) ;;
|
||||
1) echo "party: '$name' not found." >&2; exit 1 ;;
|
||||
2) exit 1 ;; # find_party_by_name printed the ambiguity hint
|
||||
esac
|
||||
else
|
||||
pick_live_party || exit 1
|
||||
fi
|
||||
|
||||
if [ "$RR_HOST_USER" = "$USER" ]; then
|
||||
echo "party knock: '$RR_PARTY_NAME' is your own party." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$(party_conn_state "$RR_SOCKET")" = ok ]; then
|
||||
echo "party knock: you are already invited. Run: party join $RR_PARTY_NAME"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Unlike cmd_invite's courtesy ping, delivery failure is surfaced:
|
||||
# the ping IS the feature. write(1) exits nonzero when the target
|
||||
# has no tty or has messages disabled (mesg n).
|
||||
if knock_send "$RR_HOST_USER" "$RR_PARTY_NAME"; then
|
||||
echo "Knocked: $RR_HOST_USER was pinged about '$RR_PARTY_NAME'."
|
||||
else
|
||||
echo "party knock: could not reach $RR_HOST_USER (no tty, or messages disabled); ask them directly." >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Resolve the party the caller hosts. If exactly one matches, sets RR_*;
|
||||
# if zero or multiple, error. Argument: optional party name to disambiguate.
|
||||
resolve_authoritative_party() {
|
||||
|
|
@ -1485,6 +1549,7 @@ dispatch() {
|
|||
close) cmd_close "$@" ;;
|
||||
join) cmd_join "$@" ;;
|
||||
leave) cmd_leave "$@" ;;
|
||||
knock) cmd_knock "$@" ;;
|
||||
invite) cmd_invite "$@" ;;
|
||||
voice|rw) cmd_voice "$@" ;;
|
||||
mute|ro) cmd_mute "$@" ;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue