From 1ece6ea076d749fcfbfcbb657f905ab2e688152a Mon Sep 17 00:00:00 2001 From: diamondburned Date: Wed, 10 Mar 2021 15:09:48 -0800 Subject: [PATCH] Rename Author to Namer; Namer to use LabelContainer This commit breaks more of the API to force all implementations of Namer to use a LabelContainer instead of just returning a text. This is done to allow updating of all labels instead of having to update the whole parent context. This allows the backend to do book-keeping of labels and images and trivially update them simultaneously without updating the parent context. The Author interface is also renamed to User. This allows the user interface to be used everywhere else outside of Message. --- cchat.go | 65 +++++++++++++++++---------------- repository/gob/repository.gob | Bin 38575 -> 38459 bytes repository/main.go | 66 +++++++++++++++++----------------- 3 files changed, 64 insertions(+), 67 deletions(-) diff --git a/cchat.go b/cchat.go index 50503f1..1c7783a 100644 --- a/cchat.go +++ b/cchat.go @@ -150,7 +150,7 @@ type MessageAttachment struct { // The frontend should override an existing author with the received ones. This // could be treated as upsert operations. type ReadIndication struct { - Author Author + User User MessageID ID } @@ -228,20 +228,6 @@ type Authenticator interface { Name() text.Rich } -// Author is the interface for an identifiable author. The interface defines -// that an author always have an ID and a name. -// -// An example of where this interface is used would be in MessageCreate's Author -// method or embedded in Typer. The returned ID may or may not be used by the -// frontend, but backends must guarantee that the Author's ID is in fact a user -// ID. -// -// The frontend may use the ID to squash messages with the same author together. -type Author interface { - Identifier - Namer -} - // Backlogger adds message history capabilities into a message container. The // backend should send old messages using the MessageCreate method of the // MessagesContainer, and the frontend should automatically sort messages based @@ -395,7 +381,7 @@ type LabelContainer interface { // Note that the frontend may give everyone an avatar regardless, or it may not // show any avatars at all. type ListMember interface { - Author + User // Secondary returns the subtext of this member. This could be anything, such as // a user's custom status or away reason. @@ -517,7 +503,7 @@ type MessageCreate interface { // backend does not implement mentioning, then false can be returned. Mentioned() bool Content() text.Rich - Author() Author + Author() User } // MessageDelete is the interface for a message delete event. @@ -583,8 +569,15 @@ type Messenger interface { // Namer requires Name() to return the name of the object. Typically, this // implies usernames for sessions or service names for services. +// +// Frontends can show the ID of the object when a name hasn't yet been set. The +// backend may immediately update the name afterwards, but assumptions should +// not be made. type Namer interface { - Name() text.Rich + // Name sets the given container to contain the name of the parent context. The + // method has no stop method; stopping is implied to be dependent on the parent + // context. As such, it's only used for updating. + Name(context.Context, LabelContainer) (err error) } // Nicknamer adds the current user's nickname. @@ -756,8 +749,8 @@ type Service interface { // A session is returned after authentication on the service. Session implements // Name(), which should return the username most of the time. It also implements -// ID(), which might be used by frontends to check against MessageAuthor.ID() -// and other things. +// ID(), which might be used by frontends to check against User.ID() and other +// things. // // A session can implement SessionSaver, which would allow the frontend to save // the session into its keyring at any time. Whether the keyring is completely @@ -812,15 +805,6 @@ type SessionSaver interface { SaveSession() map[string]string } -// Typer is an individual user that's typing. This interface is used -// interchangably in TypingIndicator and thus ServerMessageTypingIndicator as -// well. -type Typer interface { - Author - - Time() time.Time -} - // TypingContainer is a generic interface for any container that can display // users typing in the current chatbox. The typing indicator must adhere to the // TypingTimeout returned from ServerMessageTypingIndicator. The backend should @@ -832,10 +816,11 @@ type TypingContainer interface { // of typers. This function is usually not needed, as the client will take care // of removing them after TypingTimeout has been reached or other conditions // listed in ServerMessageTypingIndicator are met. - RemoveTyper(typerID ID) - // AddTyper appends the typer into the frontend's list of typers, or it pushes - // this typer on top of others. - AddTyper(typer Typer) + RemoveTyper(authorID ID) + // AddTyper appends the typer (author) into the frontend's list of typers, or it + // pushes this typer on top of others. The frontend should assume current time + // every time AddTyper is called. + AddTyper(User) } // TypingIndicator optionally extends ServerMessage to provide bidirectional @@ -906,3 +891,17 @@ type UnreadIndicator interface { // with the server and coordinating it with reasonable rate limits, if needed. MarkRead(messageID ID) } + +// User is the interface for an identifiable author. The interface defines that +// an author always have an ID and a name. +// +// An example of where this interface is used would be in MessageCreate's User +// method or embedded in Typer. The returned ID may or may not be used by the +// frontend, but backends must guarantee that the User's ID is in fact a user +// ID. +// +// The frontend may use the ID to squash messages with the same author together. +type User interface { + Identifier + Namer +} diff --git a/repository/gob/repository.gob b/repository/gob/repository.gob index e0402958e0f168088b6491649e7422681c34e979..2127c792a18ffd8571319ad0b56efc9044e80a71 100644 GIT binary patch delta 512 zcmX|6J!lkB5O#Jin7wRFR5Yn%z`|25Aqoc6fTBlm<@7K_u{goEw=e8ocHdie-*P!p z*oj~v@qwb1U?&EJEj-soth5yi(b7unEiAmup6E35^Ue2tGcUJ|w=axW!ZsE*^4PA; zK|OzbN`d(YF6yZ>`gYZ#SWcu+TzDyVn84JRJybqNr-5>9R7tnXI|_R~7sybsh@;O^ zaYSLCtC57u2}-$|$5mpwtg}vf7_mMEQN+D~DIWGQi#;kvlBG!1S|WG0rg+k0iI>*V z%@ndU&7xQZQl#ZAS?HmV3SCZe9-lAmcEQ*c7U`&acILGSFm-|MXMy0!Wv+bb!Em5i z`{c}IdpOt+0DGFu<>CLOe0J%VJ^hA=<4)@zqtJ((^OeKjhehr=H^3~8f_}PkApd-6 z9iY(Xnk#03e@D-ob0!q|m)64yCAs=-Hw^TX_D2}x-pykrbpO^*BITQIvrHd4?}4y; ze3|z3r{F6!+udvB%nToZQJc_@qN~*Xh1 p7xlY4`zFU(MxQ250}Q8;pSXM6vI@&EDz22F-s&up?XxX=YzHxxvSt7P delta 478 zcmXw$&o2W(6vy|iR*@#E8YCnpAyJ}8!~rFKG?G^9R}>eA(OtT%X}jGLL?jMeF^NRt zAQ3l0vJzDn;pAW7;_g74$$HzyT)uhVdEZaoym`13udl=#<`n&(M$+l^fzLSU)-Rd$+LBOICo$Ql=;yC~cn znZjZ#5-37>oH(|j%tqfF)%OS}A5JixDoob?IXQmo@3Ogm%pC8We}SCwJKtg@z4XI^ zdSYQqsPqJQ*SI)>IKHy{ip9uE)bdW%BM_Twcn6zwmz;(yxPl+*JFa G)BXnqnxf4B diff --git a/repository/main.go b/repository/main.go index b9ed9ab..27f7a31 100644 --- a/repository/main.go +++ b/repository/main.go @@ -544,7 +544,7 @@ var Main = Packages{ `}, Name: "ReadIndication", Fields: []StructField{ - {NamedType: NamedType{"Author", "Author"}}, + {NamedType: NamedType{"User", "User"}}, {NamedType: NamedType{"MessageID", "ID"}}, }, }}, @@ -586,14 +586,25 @@ var Main = Packages{ Namer requires Name() to return the name of the object. Typically, this implies usernames for sessions or service names for services. + + Frontends can show the ID of the object when a name hasn't yet + been set. The backend may immediately update the name + afterwards, but assumptions should not be made. `}, Name: "Namer", Methods: []Method{ - GetterMethod{ - method: method{Name: "Name"}, - Returns: []NamedType{{ - Type: MakeQual("text", "Rich"), - }}, + ContainerMethod{ + method: method{ + Comment: Comment{` + Name sets the given container to contain the name of + the parent context. The method has no stop method; + stopping is implied to be dependent on the parent + context. As such, it's only used for updating. + `}, + Name: "Name", + }, + HasContext: true, + ContainerType: "LabelContainer", }, }, }, { @@ -622,18 +633,18 @@ var Main = Packages{ }, }, { Comment: Comment{` - Author is the interface for an identifiable author. The + User is the interface for an identifiable author. The interface defines that an author always have an ID and a name. An example of where this interface is used would be in - MessageCreate's Author method or embedded in Typer. The returned + MessageCreate's User method or embedded in Typer. The returned ID may or may not be used by the frontend, but backends must - guarantee that the Author's ID is in fact a user ID. + guarantee that the User's ID is in fact a user ID. The frontend may use the ID to squash messages with the same author together. `}, - Name: "Author", + Name: "User", Embeds: []EmbeddedInterface{ {InterfaceName: "Identifier"}, {InterfaceName: "Namer"}, @@ -815,10 +826,9 @@ var Main = Packages{ }, { Comment: Comment{` A session is returned after authentication on the service. - Session implements Name(), which should return the username - most of the time. It also implements ID(), which might be - used by frontends to check against MessageAuthor.ID() and - other things. + Session implements Name(), which should return the username most + of the time. It also implements ID(), which might be used by + frontends to check against User.ID() and other things. A session can implement SessionSaver, which would allow the frontend to save the session into its keyring at any time. @@ -1559,7 +1569,7 @@ var Main = Packages{ Methods: []Method{ GetterMethod{ method: method{Name: "Author"}, - Returns: []NamedType{{Type: "Author"}}, + Returns: []NamedType{{Type: "User"}}, }, GetterMethod{ method: method{Name: "Content"}, @@ -1700,12 +1710,14 @@ var Main = Packages{ SetterMethod{ method: method{ Comment: Comment{` - AddTyper appends the typer into the frontend's list - of typers, or it pushes this typer on top of others. + AddTyper appends the typer (author) into the + frontend's list of typers, or it pushes this typer + on top of others. The frontend should assume current + time every time AddTyper is called. `}, Name: "AddTyper", }, - Parameters: []NamedType{{Name: "typer", Type: "Typer"}}, + Parameters: []NamedType{{"", "User"}}, }, SetterMethod{ method: method{ @@ -1719,21 +1731,7 @@ var Main = Packages{ `}, Name: "RemoveTyper", }, - Parameters: []NamedType{{Name: "typerID", Type: "ID"}}, - }, - }, - }, { - Comment: Comment{` - Typer is an individual user that's typing. This interface is - used interchangably in TypingIndicator and thus - ServerMessageTypingIndicator as well. - `}, - Name: "Typer", - Embeds: []EmbeddedInterface{{InterfaceName: "Author"}}, - Methods: []Method{ - GetterMethod{ - method: method{Name: "Time"}, - Returns: []NamedType{{Type: "time.Time"}}, + Parameters: []NamedType{{Name: "authorID", Type: "ID"}}, }, }, }, { @@ -1821,7 +1819,7 @@ var Main = Packages{ `}, Name: "ListMember", Embeds: []EmbeddedInterface{ - {InterfaceName: "Author"}, + {InterfaceName: "User"}, }, Methods: []Method{ GetterMethod{