Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor sidebar data source from Room[] to SidebarItem[] #24

Merged
merged 16 commits into from
Nov 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"test": "npm run lint"
},
"dependencies": {
"@prose-im/prose-sdk-js": "0.1.27",
"@prose-im/prose-sdk-js": "0.1.28",
"@prose-im/prose-core-views": "0.25.0",
"lodash.camelcase": "4.3.x",
"lodash.upperfirst": "4.3.x",
Expand Down
9 changes: 6 additions & 3 deletions src/assemblies/app/AppSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,16 @@ export default {
async addContactGroup(jidString: string): Promise<void> {
const jids = jidString.split(",").map(value => new JID(value.trim()));

// Add contact
await Broker.$room.createGroup(jids);
await Broker.$room.startConversation(jids);

BaseAlert.success("Group added", "Group has been added");
// More than one JID involved? A group was created.
if (jids.length > 1) {
BaseAlert.success("Group added", "Group has been added");
}
},

async addContactChannel(jidString: string): Promise<void> {
// TODO: also support creating a private channel w/ createPrivateChannel?
await Broker.$room.createPublicChannel(jidString);

BaseAlert.success("Channel added", "Channel has been added");
Expand Down
101 changes: 94 additions & 7 deletions src/assemblies/inbox/InboxTopbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,20 @@ layout-toolbar(
span.a-inbox-topbar__identity-value.u-bold
| {{ room.name }}

base-tooltip(
align="right"
direction="bottom"
tooltip="Toggle favorite"
class="a-inbox-topbar__identity-action"
)
base-icon(
v-if="identityFavoriteIcon"
@click="onIdentityActionFavoriteClick"
:name="identityFavoriteIcon"
size="14px"
class="a-inbox-topbar__identity-action-icon"
)

template(
v-slot:right
)
Expand Down Expand Up @@ -171,6 +185,7 @@ import { JID, Room, RoomID, RoomType } from "@prose-im/prose-sdk-js";
import Store from "@/store";

// PROJECT: COMPONENTS
import BaseAlert from "@/components/base/BaseAlert.vue";
import {
Item as PopoverItem,
ItemType as PopoverItemType
Expand Down Expand Up @@ -217,6 +232,14 @@ export default {
return Store.$history;
},

profile(): ReturnType<typeof Store.$profile.getProfile> {
return Store.$profile.getProfile(this.jid);
},

roomItem(): ReturnType<typeof Store.$room.getRoomItem> {
return this.room ? Store.$room.getRoomItem(this.room.id) : undefined;
},

originalJID(): string {
return this.jid.toString();
},
Expand All @@ -235,10 +258,6 @@ export default {
return null;
},

profile(): ReturnType<typeof Store.$profile.getProfile> {
return Store.$profile.getProfile(this.jid);
},

identityBadge(): IdentityBadge {
// Identity verified?
if (this.profile.security && this.profile.security.verification) {
Expand All @@ -255,6 +274,14 @@ export default {
};
},

identityFavoriteIcon(): string | null {
if (this.roomItem !== undefined) {
return this.roomItem.isFavorite === true ? "star.fill" : "star";
}

return null;
},

hasActionHistoryPrevious(): boolean {
return this.history.adjacent.previous.length > 0;
},
Expand Down Expand Up @@ -298,7 +325,7 @@ export default {
const items: Array<PopoverItem> = [];

Array.from(historyRawRoomIDs).forEach((historyRoomID: RoomID) => {
const historyRoom = Store.$room.getRoomByID(historyRoomID) || undefined;
const historyRoom = Store.$room.getRoom(historyRoomID) || undefined;

if (historyRoom !== undefined) {
items.push({
Expand Down Expand Up @@ -395,6 +422,34 @@ export default {
onActionHistoryDropdownClick(): void {
// Toggle popover
this.isActionHistoryPopoverVisible = !this.isActionHistoryPopoverVisible;
},

async onIdentityActionFavoriteClick(): Promise<void> {
if (this.roomItem) {
try {
const wasFavorite = this.roomItem.isFavorite || false;

// Toggle favorite mode
await this.roomItem.toggleFavorite();

// Acknowledge toggle
BaseAlert.info(
wasFavorite === true ? "Unset from favorites" : "Set as favorite",
(wasFavorite === true ? "Removed from" : "Added to") + " favorites"
);
} catch (error) {
// Alert of toggle error
this.$log.error(
`Could not toggle favorite status on room: ${this.roomItem.room.id}`,
error
);

BaseAlert.error(
"Cannot toggle favorite",
"Failed changing favorite status. Try again?"
);
}
}
}
}
};
Expand Down Expand Up @@ -431,9 +486,14 @@ $c: ".a-inbox-topbar";
color: rgb(var(--color-text-primary));
font-size: 16px;

#{$c}__identity-badge {
#{$c}__identity-badge,
#{$c}__identity-action {
margin-block-start: 1px;
}

#{$c}__identity-action {
margin-inline-start: 8px;
}
}

&--jid {
Expand All @@ -455,13 +515,40 @@ $c: ".a-inbox-topbar";
}
}

#{$c}__identity-badge {
&:hover {
#{$c}__identity-action {
visibility: visible;
}
}

#{$c}__identity-badge,
#{$c}__identity-action {
flex: 0 0 auto;
}

#{$c}__identity-badge {
+ #{$c}__identity-value {
margin-inline-start: 5px;
}
}

#{$c}__identity-action {
visibility: hidden;

#{$c}__identity-action-icon {
fill: rgb(var(--color-base-blue-normal));
display: block;
cursor: pointer;

&:hover {
fill: rgb(var(--color-base-blue-dark));
}

&:active {
fill: darken-var(var(--color-base-blue-dark), 5%);
}
}
}
}
}
</style>
1 change: 1 addition & 0 deletions src/assets/images/icons/star.fill.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/images/icons/star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 29 additions & 1 deletion src/broker/delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ class BrokerDelegate implements ProseClientDelegate {
}

clientConnected(): void {
logger.info("Client connected");

this.__eventBus.emit("client:connected");
}

Expand All @@ -48,6 +50,8 @@ class BrokerDelegate implements ProseClientDelegate {
const message = "message" in error ? error.message : "<no message>";

logger.warn(`Client disconnected. Reason: ${error.code}. ${message}`);
} else {
logger.info(`Client disconnected`);
}

this.__eventBus.emit("client:disconnected");
Expand All @@ -63,16 +67,22 @@ class BrokerDelegate implements ProseClientDelegate {
Store.$inbox.setComposing(room.id, composingUsers);
}

roomsChanged(): void {
sidebarChanged(): void {
logger.info("Sidebar changed");

Store.$room.markRoomsChanged();
Store.$room.load();
}

contactChanged(_client: ProseClient, jid: JID): void {
logger.info(`Contact changed: ${jid}`);

Store.$roster.markContactChanged(jid);
}

avatarChanged(_client: ProseClient, jid: JID): void {
logger.info(`Avatar changed: ${jid}`);

Store.$avatar.load(jid);
}

Expand All @@ -81,6 +91,12 @@ class BrokerDelegate implements ProseClientDelegate {
room: Room,
messageIDs: string[]
): Promise<void> {
logger.info(
`Messages appended in room: ${
room.id
} with identifiers: ${messageIDs.join(", ")}`
);

const messages = await room.loadMessagesWithIDs(messageIDs);

// Insert all appended messages
Expand Down Expand Up @@ -108,6 +124,12 @@ class BrokerDelegate implements ProseClientDelegate {
room: Room,
messageIDs: string[]
): void {
logger.info(
`Messages deleted in room: ${room.id} with identifiers: ${messageIDs.join(
", "
)}`
);

for (const messageID of messageIDs) {
Store.$inbox.retractMessage(room.id, messageID);
}
Expand All @@ -118,6 +140,12 @@ class BrokerDelegate implements ProseClientDelegate {
room: Room,
messageIDs: string[]
): Promise<void> {
logger.info(
`Messages updated in room: ${room.id} with identifiers: ${messageIDs.join(
", "
)}`
);

const messages = await room.loadMessagesWithIDs(messageIDs);

for (const message of messages) {
Expand Down
4 changes: 2 additions & 2 deletions src/broker/modules/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ interface SaveAvatarRequestMetadata {
* ************************************************************************* */

class BrokerModuleProfile extends BrokerModule {
async loadUserProfile(jid: JID): Promise<UserProfile | undefined> {
async loadUserProfile(jid: JID): Promise<UserProfile | void> {
// XEP-0292: vCard4 Over XMPP
// https://xmpp.org/extensions/xep-0292.html

Expand All @@ -56,7 +56,7 @@ class BrokerModuleProfile extends BrokerModule {
return await this._client.client?.loadUserProfile(jid);
}

async loadUserMetadata(jid: JID): Promise<UserMetadata | undefined> {
async loadUserMetadata(jid: JID): Promise<UserMetadata | void> {
// XEP-0012: Last Activity + XEP-0202: Entity Time
// https://xmpp.org/extensions/xep-0012.html + \
// https://xmpp.org/extensions/xep-0202.html
Expand Down
33 changes: 8 additions & 25 deletions src/broker/modules/room.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,11 @@
* ************************************************************************* */

// NPM
import { Channel, JID, Room } from "@prose-im/prose-sdk-js";
import { Channel, JID, SidebarItem } from "@prose-im/prose-sdk-js";

// PROJECT: BROKER
import BrokerModule from "@/broker/modules";

// PROJECT: STORES
import Store from "@/store";

/**************************************************************************
* CLASS
* ************************************************************************* */
Expand All @@ -26,40 +23,26 @@ class BrokerModuleRoom extends BrokerModule {
await this._client.client?.startObservingRooms();
}

connectedRooms(): Room[] {
return this._client.client?.connectedRooms() || [];
sidebarItems(): SidebarItem[] {
return this._client.client?.sidebarItems() || [];
}

async loadPublicChannels(): Promise<Array<Channel>> {
return (await this._client.client?.loadPublicChannels()) || [];
}

async createGroup(participants: Array<JID>): Promise<void> {
const room = (await this._client.client?.createGroup(
async startConversation(participants: Array<JID>): Promise<void> {
await this._client.client?.startConversation(
participants.map(jid => jid.toString())
)) as Room;

if (room) {
Store.$room.insertRoom(room);
}
);
}

async createPublicChannel(name: string): Promise<void> {
const room = (await this._client.client?.createPublicChannel(name)) as Room;

if (room) {
Store.$room.insertRoom(room);
}
await this._client.client?.createPublicChannel(name);
}

async createPrivateChannel(name: string): Promise<void> {
const room = (await this._client.client?.createPrivateChannel(
name
)) as Room;

if (room) {
Store.$room.insertRoom(room);
}
await this._client.client?.createPrivateChannel(name);
}
}

Expand Down
Loading
Loading