Skip to content

Commit 52f1d93

Browse files
committed
Add "Copy ID" button to room entries and related styling
- Introduced a "Copy ID" button for each room entry in the menu, enabling users to copy room or DM partner IDs to the clipboard. - Added `_copyToClipboard` helper method for clipboard operations. - Updated `stylesheet.css` with styles for the new "Copy ID" button, including hover and active states. - Enhanced room data processing to store `dmPartnerId` for DMs.
1 parent c53d884 commit 52f1d93

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

extension.js

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ const MatrixIndicator = GObject.registerClass(
107107
Gio.AppInfo.launch_default_for_uri(uri, null);
108108
}
109109

110+
_copyToClipboard(text) {
111+
const clipboard = St.Clipboard.get_default();
112+
clipboard.set_text(St.ClipboardType.CLIPBOARD, text);
113+
}
114+
110115
_buildMenu(rooms = []) {
111116
this.menu.removeAll();
112117
if (rooms.length === 0) {
@@ -133,6 +138,25 @@ const MatrixIndicator = GObject.registerClass(
133138

134139
let labelText = room.unread > 0 ? `<b>(${room.unread}) ${room.name}</b>` : room.name;
135140
item.label.get_clutter_text().set_markup(labelText);
141+
item.label.x_expand = true;
142+
143+
// Copy ID button
144+
const copyButton = new St.Button({
145+
child: new St.Icon({
146+
icon_name: 'edit-copy-symbolic',
147+
icon_size: 14,
148+
}),
149+
style_class: 'matrix-copy-button',
150+
can_focus: true,
151+
});
152+
153+
copyButton.connect('clicked', () => {
154+
this._copyToClipboard(room.dmPartnerId || room.id);
155+
this.menu.close();
156+
return Clutter.EVENT_STOP;
157+
});
158+
159+
item.add_child(copyButton);
136160

137161
item.connect('activate', () => {
138162
this._openMatrixClient(room.id);
@@ -236,17 +260,27 @@ const MatrixIndicator = GObject.registerClass(
236260
// Show room if it has unread messages OR it's a favorite
237261
if (unread > 0 || hasFavTag) {
238262
let name = null;
263+
let dmPartnerId = null;
264+
239265
const nameEv = roomData.state?.events?.find(e => e.type === 'm.room.name');
240266
if (nameEv?.content?.name)
241267
name = nameEv.content.name;
242268

243-
if (!name && roomData.summary?.['m.heroes']?.length > 0) {
269+
if (roomData.summary?.['m.heroes']?.length > 0) {
244270
const heroes = roomData.summary['m.heroes'];
245-
const heroNames = heroes.map((h) => {
246-
const m = roomData.state?.events?.find(e => e.type === 'm.room.member' && e.state_key === h);
247-
return m?.content?.displayname || h.split(':')[0].replace('@', '');
248-
});
249-
name = heroNames.join(', ');
271+
272+
// If it's a DM (no explicit room name and usually 1 hero)
273+
if (!name && heroes.length === 1) {
274+
dmPartnerId = heroes[0];
275+
}
276+
277+
if (!name) {
278+
const heroNames = heroes.map((h) => {
279+
const m = roomData.state?.events?.find(e => e.type === 'm.room.member' && e.state_key === h);
280+
return m?.content?.displayname || h.split(':')[0].replace('@', '');
281+
});
282+
name = heroNames.join(', ');
283+
}
250284
}
251285

252286
// Get timestamp from the last event for sorting
@@ -258,6 +292,7 @@ const MatrixIndicator = GObject.registerClass(
258292
roomList.push({
259293
name: name || 'Unnamed Room',
260294
id: roomId,
295+
dmPartnerId,
261296
unread,
262297
timestamp,
263298
encrypted: isEncrypted,

stylesheet.css

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,20 @@
2323
.popup-menu-icon {
2424
margin-right: 8px;
2525
padding: 2px;
26+
}
27+
28+
.matrix-copy-button {
29+
padding: 4px;
30+
border-radius: 4px;
31+
transition: background-color 0.2s;
32+
margin-left: 12px;
33+
margin-right: 4px;
34+
}
35+
36+
.matrix-copy-button:hover {
37+
background-color: rgba(255, 255, 255, 0.1);
38+
}
39+
40+
.matrix-copy-button:active {
41+
background-color: rgba(255, 255, 255, 0.2);
2642
}

0 commit comments

Comments
 (0)