Skip to content

Commit a302686

Browse files
authored
Merge pull request #244 from 67P/feature/xmpp_pending_messages
Pending status for outgoing XMPP messages
2 parents 13db2a5 + 65a107f commit a302686

File tree

10 files changed

+80
-43
lines changed

10 files changed

+80
-43
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[![Build Status](https://travis-ci.com/67P/hyperchannel.svg?branch=master)](https://travis-ci.org/67P/hyperchannel)
2-
[![devDependency Status](https://david-dm.org/67P/hyperchannel/dev-status.svg)](https://david-dm.org/67P/hyperchannel#info=devDependencies)
32
[![Code Climate](https://img.shields.io/codeclimate/maintainability/67P/hyperchannel.svg)](https://codeclimate.com/github/67P/hyperchannel)
3+
[![devDependency Status](https://david-dm.org/67P/hyperchannel/dev-status.svg)](https://david-dm.org/67P/hyperchannel#info=devDependencies)
44

55
# Hyperchannel (pre-alpha!)
66

app/components/message-chat/component.js

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ export default class MessageChatComponent extends Component {
4747
return htmlSafe(out);
4848
}
4949

50+
get pendingClass () {
51+
return this.args.message.pending ? 'text-gray-500' : '';
52+
}
53+
5054
@action
5155
usernameClick (username) {
5256
this.args.onUsernameClick(username);
+7-6
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
<div class="chat-message">
2-
<span class="chat-message__username"
3-
data-username={{@message.nickname}}
4-
onclick={{fn this.usernameClick @message.nickname}}>
1+
<div class="chat-message break-words">
2+
<span data-username={{@message.nickname}}
3+
onclick={{fn this.usernameClick @message.nickname}}
4+
class="mr-1 font-bold {{this.pendingClass}}" >
55
{{@message.nickname}}:
66
</span>
77

8-
<time class="chat-message__date" datetime={{this.datetime}} title={{this.dateTitle}}>
8+
<time datetime={{this.datetime}} title={{this.dateTitle}}
9+
class="block float-right text-sm text-gray-300" >
910
{{moment-format @message.date "HH:mm"}}
1011
</time>
1112

12-
<span class="chat-message__message">
13+
<span class="{{this.pendingClass}}">
1314
{{this.formattedContent}}
1415
</span>
1516
</div>

app/controllers/base_channel.js

+15-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { alias } from '@ember/object/computed';
44
import { inject as service } from '@ember/service';
55
import { isPresent } from '@ember/utils';
66
import { tracked } from '@glimmer/tracking';
7+
import Channel from 'hyperchannel/models/channel';
78
import Message from 'hyperchannel/models/message';
89

910
export default class BaseChannelController extends Controller {
@@ -16,14 +17,23 @@ export default class BaseChannelController extends Controller {
1617

1718
@alias('application.showChannelMenu') showChannelMenu;
1819

19-
createMessage (message, type) {
20-
return new Message({
20+
createMessage (content, type) {
21+
const message = new Message({
2122
type: type,
2223
date: new Date(),
2324
// TODO nickname per channel
2425
nickname: this.model.account.nickname,
25-
content: message
26+
content: content
2627
});
28+
29+
// We only receive our own message from XMPP MUCs (but not DMs)
30+
// TODO implement message carbons or another way of verifying sent status
31+
if (this.model.protocol === 'XMPP' &&
32+
(this.model instanceof Channel)) {
33+
message.pending = true;
34+
}
35+
36+
return message;
2737
}
2838

2939
@computed('router.currentRouteName')
@@ -57,12 +67,10 @@ export default class BaseChannelController extends Controller {
5767
sendMessage (newMessage) {
5868
const message = this.createMessage(newMessage, 'message-chat');
5969

60-
this.coms.transferMessage(
61-
this.model,
62-
message.content
63-
);
70+
this.coms.transferMessage(this.model, message.content);
6471

6572
this.model.addMessage(message);
73+
6674
this.newMessage = null;
6775
}
6876

app/models/base_channel.js

+12
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,18 @@ export default class BaseChannel {
132132
}
133133
}
134134

135+
confirmPendingMessage (content) {
136+
const message = this.messages.filterBy('pending')
137+
.findBy('content', content);
138+
139+
if (isPresent(message)) {
140+
message.pending = false;
141+
return true;
142+
} else {
143+
return false;
144+
}
145+
}
146+
135147
addUser(username) {
136148
if (!this.userList.includes(username)) {
137149
this.userList.pushObject(username);

app/models/message.js

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export default class Message {
66
@tracked date = null;
77
@tracked nickname = null;
88
@tracked content = null;
9+
@tracked pending = null;
910

1011
constructor (props) {
1112
Object.assign(this, props);

app/services/sockethub-xmpp.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -188,12 +188,17 @@ export default class SockethubXmppService extends Service {
188188
if (isEmpty(message.object.content)) return;
189189

190190
const channel = this.findOrCreateChannelForMessage(message);
191-
const channelMessage = channelMessageFromSockethubObject(message);
192191

193-
// TODO should check for message and update sent status if exists
194-
if (channelMessage.nickname !== channel.account.nickname) {
195-
channel.addMessage(channelMessage);
192+
// TODO implement message carbons
193+
// https://xmpp.org/extensions/xep-0280.html
194+
if (message.actor.displayName &&
195+
(message.actor.displayName === channel.account.nickname)) {
196+
const pendingConfirmed = channel.confirmPendingMessage(message.object.content);
197+
if (pendingConfirmed) return;
196198
}
199+
200+
const channelMessage = channelMessageFromSockethubObject(message);
201+
channel.addMessage(channelMessage);
197202
}
198203

199204
/**

app/styles/components/message-chat.scss

-25
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,6 @@
4242
font-style: italic;
4343
}
4444

45-
&__date {
46-
display: block;
47-
float: right;
48-
font-size: 12px;
49-
color: #ccc;
50-
}
51-
52-
&__username {
53-
margin-right: 0.2em;
54-
font-weight: bold;
55-
56-
// &[data-username=raucao] {
57-
// background: url(/img/avatar-sk.png) 0 2px no-repeat;
58-
// }
59-
// &[data-username=silverbucket] {
60-
// background: url(/img/avatar-sb.png) 0 2px no-repeat;
61-
// }
62-
// &[data-username=galfert] {
63-
// background: url(/img/avatar-ga.jpeg) 0 2px no-repeat;
64-
// }
65-
}
66-
67-
&__message {
68-
}
69-
7045
a {
7146
text-decoration: underline;
7247
color: #339;

tests/fixtures/accounts.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export const ircAccount = new IrcAccount({
77
});
88

99
export const xmppAccount = new XmppAccount({
10+
nickname: 'jimmy',
1011
username: '[email protected]'
1112
});

tests/unit/services/sockethub-xmpp-test.js

+30
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { module, test } from 'qunit';
22
import { setupTest } from 'ember-qunit';
33
import Channel from 'hyperchannel/models/channel';
4+
import Message from 'hyperchannel/models/message';
45
import { xmppAccount } from '../../fixtures/accounts';
56

67
module('Unit | Service | sockethub xmpp', function(hooks) {
@@ -99,6 +100,35 @@ module('Unit | Service | sockethub xmpp', function(hooks) {
99100
assert.equal(channel.messages.lastObject.content, 'hello world');
100101
});
101102

103+
test('#addMessageToChannel updates pending status when receiving an outgoing message', function(assert) {
104+
const channel = new Channel({ account: xmppAccount, name: '[email protected]' });
105+
const outgoingMessage = new Message({
106+
type: 'message-chat',
107+
date: new Date(),
108+
nickname: 'jimmy',
109+
content: 'yo, gang!',
110+
pending: true
111+
});
112+
channel.messages.pushObject(outgoingMessage);
113+
114+
const comsService = this.owner.factoryFor('service:coms').create({
115+
accounts: [ xmppAccount ], channels: [ channel ]
116+
});
117+
const service = this.owner.factoryFor('service:sockethub-xmpp').create({ coms: comsService });
118+
119+
const message = {
120+
actor: { '@id': '[email protected]/jimmy', '@type': 'person', displayName: 'jimmy' },
121+
target: { '@id': '[email protected]', '@type': 'room' },
122+
object: { '@type': 'message', content: 'yo, gang!' }
123+
};
124+
125+
service.addMessageToChannel(message);
126+
127+
assert.equal(channel.messages.filterBy('nickname', 'jimmy').length, 1);
128+
assert.equal(channel.messages.lastObject.content, 'yo, gang!');
129+
assert.notOk(channel.messages.lastObject.pending);
130+
});
131+
102132
test('#createUserChannel', function(assert) {
103133
const comsService = this.owner.factoryFor('service:coms').create({
104134
accounts: [ xmppAccount ]

0 commit comments

Comments
 (0)