Skip to content

Commit

Permalink
Pronouns (fix #189)
Browse files Browse the repository at this point in the history
  • Loading branch information
edemaine committed Feb 6, 2022
1 parent e8c40f2 commit 9f2b67c
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ instead of version numbers.
## 2022-02-06

* Rooms now have a dropdown list of users (first button after room title).
* This list shows the users' pronouns, as set in Settings.
[[#189](https://github.com/edemaine/comingle/issues/189)]
* Admins can kick a user from the current room (e.g. to remove idle users).
Users can still rejoin the room if they want, unless the room is locked.
[[#122](https://github.com/edemaine/comingle/issues/122)]
Expand Down
16 changes: 11 additions & 5 deletions client/Meeting.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {Room, setRoomTitle} from './Room'
import {Settings} from './Settings'
import {Welcome} from './Welcome'
import {VisitMeeting} from './VisitedMeetings'
import {useName} from './Name'
import {useName, usePronouns} from './Name'
import {Meetings} from '/lib/meetings'
import {Rooms} from '/lib/rooms'
import {PresenceStream} from '/lib/presence'
Expand Down Expand Up @@ -145,6 +145,7 @@ export Meeting = React.memo ->
, [location.hash]
presenceId = getPresenceId()
name = useName()
pronouns = usePronouns()

## `starredOld` is remembered across the browser (all tabs), and may contain
## a list of previously starred rooms. In this case, `starredHasOld`
Expand All @@ -168,6 +169,7 @@ export Meeting = React.memo ->
meeting: meetingId
secret: meetingSecret
name: name
pronouns: pronouns
rooms:
joined: []
starred: starred
Expand All @@ -176,20 +178,24 @@ export Meeting = React.memo ->
presence.rooms.joined.push node.getId()
last = lastPresence.current
unless last? and last.meeting == presence.meeting and
last.name == presence.name and last.secret == presence.secret and
last.name == presence.name and
last.pronouns == presence.pronouns and
last.secret == presence.secret and
sameSorted(last.rooms.joined, presence.rooms.joined) and
sameSorted(last.rooms.starred, presence.rooms.starred)
Meteor.call 'presenceUpdate', presence
lastPresence.current = presence
undefined
## Send presence when name changes, when list of starred rooms changes, or
## when we reconnect to server (so server may have deleted our presence).
## Send presence when
## * name or pronouns change
## * list of starred rooms changes
## * we reconnect to server (so server may have deleted our presence).
useTracker ->
if Meteor.status().connected
lastPresence.current = null # force update on reconnect
updatePresence true
, []
useEffect updatePresence, [meetingId, name, meetingSecret, starred.join '\t']
useEffect updatePresence, [meetingId, name, pronouns, meetingSecret, starred.join '\t']

## Process PresenceStream events: Leave rooms we're kicked from.
useEffect ->
Expand Down
28 changes: 28 additions & 0 deletions client/Name.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,31 @@ export Name = React.memo ->
</Card.Body>
</Card>
Name.displayName = 'Name'

pronounsVar = new LocalStorageVar 'pronouns', '', sync: true
export usePronouns = -> pronounsVar.use()
export getPronouns = -> pronounsVar.get()

export Pronouns = React.memo ->
[pronouns, setPronouns] = useState -> pronounsVar.get()
pronounsDebounce = useDebounce pronouns, 500

## Synchronize global with form state
useTracker ->
setPronouns pronounsVar.get()
, []
useLayoutEffect ->
pronounsVar.set pronounsDebounce
undefined
, [pronounsDebounce]

<Card>
<Card.Header className="tight">
Your Pronouns:
</Card.Header>
<Card.Body>
<Form.Control type="text" placeholder="they" className="pronouns"
value={pronouns} onChange={(e) -> setPronouns e.target.value}/>
</Card.Body>
</Card>
Pronouns.displayName = 'Pronouns'
5 changes: 5 additions & 0 deletions client/Room.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,11 @@ export RoomUsers = React.memo ({className, room}) ->
}
&nbsp;
{user.name}
{if user.pronouns
<span className="pronouns">
({user.pronouns})
</span>
}
</span>
</Dropdown.ItemText>
}
Expand Down
2 changes: 2 additions & 0 deletions client/Settings.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Card, Form} from 'react-bootstrap'
import {LocalStorageVar, StorageDict} from './lib/useLocalStorage'
import {MeetingTitle} from './MeetingTitle'
import {MeetingSecret, useMeetingAdmin} from './MeetingSecret'
import {Pronouns} from './Name'

export Settings = React.memo ->
admin = useMeetingAdmin()
Expand All @@ -19,6 +20,7 @@ export Settings = React.memo ->
</Card.Body>
</Card>
<div className="sidebar">
<Pronouns/>
<MeetingTitle/>
<MeetingSecret/>
</div>
Expand Down
6 changes: 6 additions & 0 deletions client/main.styl
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ nav
/.presence &
font-weight: bold

span.pronouns
opacity: 0.8
margin-left: 0.25rem
font-weight: normal
font-style: italic

.btn-outline-warning
color: var(--warning-fg)
border-color: var(--warning-fg)
Expand Down
2 changes: 2 additions & 0 deletions lib/presence.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Meteor.methods
meeting: Match.Where validId
secret: Match.Maybe String
name: String
pronouns: Match.Optional String
rooms:
joined: [Match.Where validId]
starred: [Match.Where validId]
Expand Down Expand Up @@ -53,6 +54,7 @@ Meteor.methods
$set: Object.assign (setAdmin ? {}),
meeting: presence.meeting
name: presence.name
pronouns: presence.pronouns
rooms: presence.rooms
$setOnInsert:
id: presence.id
Expand Down
5 changes: 3 additions & 2 deletions server/log.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ export logPresence = (presence) ->
diff.id = presence.id
diff.meeting = presence.meeting
diff.updated = presence.updated
## Diff name and rooms
## Diff name, pronouns, admin, and rooms
diff.name = presence.name unless old? and old.name == presence.name
diff.pronouns = presence.pronouns unless old? and old.pronouns == presence.pronouns
diff.admin = presence.admin unless old? and old.admin == presence.admin
diff.rooms = {}
for key of presence.rooms
unless old? and sameSorted old.rooms[key], presence.rooms[key]
diff.rooms[key] = presence.rooms[key]
delete diff.rooms unless (key for key of diff.rooms).length
## Check for no-op update
return {old} unless diff.name? or diff.admin? or diff.rooms?
return {old} unless diff.name? or diff.pronouns? or diff.admin? or diff.rooms?
## Write log. Use rawCollection() to let server assign _id,
## which guarantees no conflict.
Log.rawCollection().insert diff
Expand Down

0 comments on commit 9f2b67c

Please sign in to comment.