mirror of https://github.com/sipwise/ngcp-csc.git
Change-Id: I3062559fc0b26efc8890131d9e12dd3d71f3d5aachanges/12/9212/2
parent
649b97df7d
commit
e4376d5687
@ -0,0 +1,16 @@
|
||||
Ext.define('NgcpCsc.model.ChatList', {
|
||||
extend: 'Ext.data.Model',
|
||||
fields: [{
|
||||
type: 'int',
|
||||
name: 'id'
|
||||
}, {
|
||||
type: 'string',
|
||||
name: 'name'
|
||||
}, {
|
||||
type: 'string',
|
||||
name: 'thumbnail'
|
||||
}, {
|
||||
type: 'boolean',
|
||||
name: 'online'
|
||||
}]
|
||||
});
|
@ -0,0 +1,20 @@
|
||||
Ext.define('NgcpCsc.model.ChatNotification', {
|
||||
extend: 'Ext.data.Model',
|
||||
fields: [{
|
||||
name: '_id'
|
||||
}, {
|
||||
name: 'parent_id'
|
||||
}, {
|
||||
name: 'name'
|
||||
}, {
|
||||
name: 'source'
|
||||
}, {
|
||||
name: 'date'
|
||||
}, {
|
||||
name: 'isActive'
|
||||
}, {
|
||||
name: 'time'
|
||||
}, {
|
||||
name: 'content'
|
||||
}]
|
||||
});
|
@ -0,0 +1,18 @@
|
||||
Ext.define('NgcpCsc.store.Chat', {
|
||||
extend: 'Ext.data.Store',
|
||||
|
||||
storeId: 'Chat',
|
||||
|
||||
model: 'NgcpCsc.model.ChatNotification',
|
||||
|
||||
autoLoad: true,
|
||||
|
||||
proxy: {
|
||||
type: 'ajax',
|
||||
url: '/resources/data/chat.json',
|
||||
reader: {
|
||||
type: 'json',
|
||||
rootProperty: 'data'
|
||||
}
|
||||
}
|
||||
});
|
@ -0,0 +1,25 @@
|
||||
Ext.define('NgcpCsc.store.ChatList', {
|
||||
extend: 'Ext.data.Store',
|
||||
|
||||
alias: 'store.chatlist',
|
||||
|
||||
storeId: 'ChatList',
|
||||
|
||||
model: 'NgcpCsc.model.ChatList',
|
||||
|
||||
autoLoad: true,
|
||||
|
||||
proxy: {
|
||||
type: 'ajax',
|
||||
url: '/resources/data/chatlist.json',
|
||||
reader: {
|
||||
type: 'json',
|
||||
rootProperty: 'data'
|
||||
}
|
||||
},
|
||||
|
||||
sorters: {
|
||||
direction: 'DESC',
|
||||
property: 'online'
|
||||
}
|
||||
});
|
@ -0,0 +1,295 @@
|
||||
.user-notifications {
|
||||
padding: 15px;
|
||||
background: #fff;
|
||||
|
||||
.x-view-item-focused {
|
||||
outline: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.timeline-item {
|
||||
.line-wrap {
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 50px;
|
||||
height: 100%;
|
||||
border-right: solid 2px $base-color;
|
||||
left: 0;
|
||||
top: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
.profile-pic-wrap {
|
||||
width: 100px;
|
||||
float: left;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
background: $lightest-color;
|
||||
padding: 5px 0;
|
||||
|
||||
img {
|
||||
height: 46px;
|
||||
width: 46px;
|
||||
@include border-radius($circle-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
.contents-wrap {
|
||||
margin: 0 0 15px 110px;
|
||||
border: 1px solid $base-border-color;
|
||||
position: relative;
|
||||
padding: 15px;
|
||||
white-space: normal;
|
||||
|
||||
&:after,
|
||||
&:before {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:before {
|
||||
border-top: 9px solid transparent;
|
||||
border-bottom: 9px solid transparent;
|
||||
border-right: 9px solid $base-border-color;
|
||||
margin: 15px 0 0 -9px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
border-top: 9px solid transparent;
|
||||
border-bottom: 9px solid transparent;
|
||||
border-right: 9px solid $lightest-color;
|
||||
margin: 15px 0 0 -8px;
|
||||
}
|
||||
|
||||
.followed-by,
|
||||
.shared-by {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
a {
|
||||
color: $base-color;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.shared-img {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.job-meeting a {
|
||||
color: $base-color;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.article-comment {
|
||||
border-left: 5px solid $base-border-color;
|
||||
padding: 10px 20px;
|
||||
|
||||
span {
|
||||
margin-right: 10px;
|
||||
color: $article-comment-color;
|
||||
}
|
||||
}
|
||||
|
||||
.followed-by {
|
||||
img {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
@include border-radius($circle-border-radius);
|
||||
margin-right: 5px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.followed-by-inner {
|
||||
margin-left: 40px;
|
||||
padding: 5px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.comments {
|
||||
margin-bottom: 10px;
|
||||
cursor: pointer;
|
||||
|
||||
img.profile-icon {
|
||||
height: 50px;
|
||||
width: 50px;
|
||||
border: 2px solid $base-border-color;
|
||||
@include border-radius($circle-border-radius);
|
||||
float: left;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
float: left;
|
||||
|
||||
span {
|
||||
margin-left: 8px;
|
||||
font-size: 18px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
.from-now {
|
||||
float: right;
|
||||
|
||||
span {
|
||||
margin-right: 5px;
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.content-wrap {
|
||||
margin-left: 65px;
|
||||
|
||||
.content {
|
||||
margin-bottom: 15px;
|
||||
white-space: normal;
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
&.sub-comments {
|
||||
margin: 0 0 10px 60px;
|
||||
|
||||
.like-comment-btn-wrap {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.like-comment-btn-wrap {
|
||||
text-align: right;
|
||||
padding-bottom: 15px;
|
||||
|
||||
button {
|
||||
margin-left: 15px;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
background-color: $like-comment-btn-background-color;
|
||||
font-size: 14px;
|
||||
color: $color;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.menu-item-common {
|
||||
padding-right: 20px;
|
||||
position: absolute;
|
||||
font-family: FontAwesome;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.navigation-email {
|
||||
// @include box-shadow(0px,2px,8px,0px,rgba(0,0,0,.15));
|
||||
@include box-shadow(0, 1px, 2px, 0, rgba(0,0,0,0.2));
|
||||
|
||||
&.x-menu-default {
|
||||
border-width: 0;
|
||||
}
|
||||
|
||||
.x-menu-header {
|
||||
line-height: 20px;
|
||||
background-color: $lightest-color;
|
||||
padding: 22px 15px;
|
||||
border-bottom: 1px solid #ccc !important;
|
||||
|
||||
.x-title-icon-wrap {
|
||||
width: 40px;
|
||||
padding-right: 28px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.x-title-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.x-menu-item-icon-default {
|
||||
padding-top: 10px;
|
||||
padding-left: 12px;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.x-menu-item {
|
||||
line-height: 50px;
|
||||
|
||||
.x-menu-item-text-default.x-menu-item-indent-no-separator {
|
||||
margin-left: 56px;
|
||||
}
|
||||
|
||||
&.online-user {
|
||||
.x-menu-item-text-default.x-menu-item-indent-no-separator {
|
||||
margin-left: 18px;
|
||||
}
|
||||
|
||||
.x-menu-item-link:after {
|
||||
color: $online-menu-item-color;
|
||||
content: "\f111";
|
||||
@extend .menu-item-common;
|
||||
}
|
||||
|
||||
&.x-menu-item-active {
|
||||
.x-menu-item-link:after {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.offline-user {
|
||||
.x-menu-item-link:after {
|
||||
color: $offline-menu-item-color;
|
||||
content: "\f111";
|
||||
@extend .menu-item-common;
|
||||
}
|
||||
|
||||
.x-menu-item-text-default.x-menu-item-indent-no-separator {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.x-menu-item-link:after {
|
||||
@extend .menu-item-common;
|
||||
color: $default-menu-item-color;
|
||||
content: "\f105";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.new-message-cont {
|
||||
margin-left: 203px;
|
||||
}
|
||||
|
||||
.submit-new-message {
|
||||
float: right;
|
||||
top: 0 !important;
|
||||
}
|
||||
|
||||
.hide-pm {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.private-conversation-text {
|
||||
padding: 30px;
|
||||
}
|
@ -1 +0,0 @@
|
||||
$dialog-trigger-color : #e5e5e5;
|
@ -0,0 +1,3 @@
|
||||
$like-comment-btn-background-color: #f4f4f4;
|
||||
$like-comment-btn-color: #979797;
|
||||
$article-comment-color: #eee;
|
@ -0,0 +1,60 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.Chat', {
|
||||
extend: 'Ext.panel.Panel',
|
||||
|
||||
xtype: 'chat',
|
||||
|
||||
viewModel: 'chat',
|
||||
|
||||
controller: 'chat',
|
||||
|
||||
layout: 'hbox',
|
||||
|
||||
items: [{
|
||||
xtype: 'chatlist',
|
||||
width: 200,
|
||||
padding: '10 20 20',
|
||||
height: '100%'
|
||||
}, {
|
||||
xtype: 'tabpanel',
|
||||
width: '90%',
|
||||
height: '100%',
|
||||
items: [{
|
||||
title: Ngcp.csc.locales.chat.title[localStorage.getItem('languageSelected')],
|
||||
xtype: 'chat-notifications',
|
||||
id: 'chat-notifications',
|
||||
scrollable: true,
|
||||
bind: {
|
||||
store: '{notifications}'
|
||||
}
|
||||
}]
|
||||
}],
|
||||
|
||||
dockedItems: [{
|
||||
xtype: 'toolbar',
|
||||
cls: 'new-message-cont',
|
||||
fixed: true,
|
||||
padding: '0 0 10 0',
|
||||
dock: 'bottom',
|
||||
items: [{
|
||||
xtype: 'textarea',
|
||||
bind: {
|
||||
value: '{new_message}'
|
||||
},
|
||||
cls: 'new-message',
|
||||
name: 'new-message',
|
||||
enableKeyEvents: true,
|
||||
height: 100,
|
||||
width: '95%',
|
||||
listeners: {
|
||||
keypress: 'onPressEnter'
|
||||
},
|
||||
emptyText: Ngcp.csc.locales.chat.msg_box.empty_text[localStorage.getItem('languageSelected')]
|
||||
}, {
|
||||
xtype: 'button',
|
||||
cls: 'submit-new-message',
|
||||
text: Ngcp.csc.locales.common.submit[localStorage.getItem('languageSelected')],
|
||||
handler: 'onPressSubmitBtn'
|
||||
}]
|
||||
}]
|
||||
|
||||
});
|
@ -0,0 +1,80 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatController', {
|
||||
extend: 'Ext.app.ViewController',
|
||||
|
||||
alias: 'controller.chat',
|
||||
|
||||
listen: {
|
||||
controller: {
|
||||
'#chatlist': {
|
||||
openpmtab: 'openPM'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onPressEnter: function(field, e) {
|
||||
if (e.getKey() == e.ENTER) {
|
||||
e.preventDefault();
|
||||
this.submitMessage();
|
||||
}
|
||||
},
|
||||
|
||||
onPressSubmitBtn: function(field, e) {
|
||||
this.submitMessage();
|
||||
},
|
||||
|
||||
submitMessage: function(msg, user) {
|
||||
var message = msg || this.getViewModel().get('new_message');
|
||||
if (message.length < 1)
|
||||
return;
|
||||
var chatStore = this.getView().down('tabpanel').getActiveTab().getStore('notifications');
|
||||
var lastMsg = chatStore.getAt(chatStore.getCount() - 1) || this.getViewModel().getStore('notifications').findRecord('id', this.getView().down('tabpanel').getActiveTab().name);
|
||||
var date = new Date();
|
||||
var minutes = date.getMinutes();
|
||||
var hour = date.getHours();
|
||||
var day = date.getDate();
|
||||
var month = date.getMonth() + 1;
|
||||
var messageModel = Ext.create('NgcpCsc.model.ChatNotification', {
|
||||
/// "id": (user) ? user.get('id') : 0,
|
||||
"name": (user) ? user.get('name') : localStorage.getItem('username'),
|
||||
"date": Ext.String.format("{0}.{1}", day, month),
|
||||
"isActive": true,
|
||||
"time": Ext.String.format("{0}:{1}", hour, minutes),
|
||||
"thumbnail": (user) ? user.get('thumbnail') : "resources/images/user-profile/2.png",
|
||||
"content": message
|
||||
});
|
||||
chatStore.add(messageModel);
|
||||
this.clearMsg();
|
||||
this.focusLastMsg();
|
||||
},
|
||||
|
||||
clearMsg: function() {
|
||||
this.getView().down('[name=new-message]').reset();
|
||||
},
|
||||
|
||||
focusLastMsg: function(rec) {
|
||||
var chatCmp = this.getView().down('tabpanel').getActiveTab();
|
||||
chatCmp.scrollTo(0, chatCmp.getEl().dom.scrollHeight);
|
||||
},
|
||||
|
||||
openPM: function(item, rec) {
|
||||
var tab = this.getView().down('[name=' + rec.get('id') + ']');
|
||||
if (rec.get('name') == 'administrator') // hardcoded administrator
|
||||
return;
|
||||
if (!tab) {
|
||||
tab = this.getView().down('tabpanel').add({
|
||||
xtype: 'chat-notifications',
|
||||
title: rec.get('name'),
|
||||
closable: true,
|
||||
scrollable: true,
|
||||
cls: 'private-conversation-text',
|
||||
deferEmptyText: false,
|
||||
emptyText: Ext.String.format(Ngcp.csc.locales.chat.start_conversation[localStorage.getItem('languageSelected')], rec.get('name')),
|
||||
name: rec.get('id'),
|
||||
store: Ext.create('Ext.data.Store', {
|
||||
model: 'NgcpCsc.model.ChatNotification'
|
||||
})
|
||||
});
|
||||
}
|
||||
this.getView().down('tabpanel').setActiveTab(tab);
|
||||
}
|
||||
});
|
@ -0,0 +1,23 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatList', {
|
||||
extend: 'Ext.menu.Menu',
|
||||
|
||||
alias: 'widget.chatlist',
|
||||
|
||||
viewModel: {
|
||||
type: 'chatlist'
|
||||
},
|
||||
|
||||
controller: 'chatlist',
|
||||
|
||||
title: Ngcp.csc.locales.chat.title[localStorage.getItem('languageSelected')],
|
||||
|
||||
cls: 'navigation-email',
|
||||
|
||||
iconCls: 'x-fa fa-group',
|
||||
|
||||
floating: false,
|
||||
|
||||
listeners: {
|
||||
click: 'itemListClicked'
|
||||
}
|
||||
});
|
@ -0,0 +1,51 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatListController', {
|
||||
extend: 'Ext.app.ViewController',
|
||||
|
||||
alias: 'controller.chatlist',
|
||||
|
||||
id: 'chatlist', // needed as reference in ChatController listeners
|
||||
|
||||
init: function() {
|
||||
var me = this,
|
||||
friendsStore = me.getViewModel().getStore('friends');
|
||||
|
||||
//Trigger local sorting once new data is available
|
||||
friendsStore.on('load', function(store) {
|
||||
store.sort();
|
||||
});
|
||||
|
||||
//Sort locally and then update menu
|
||||
friendsStore.on('sort', function(store) {
|
||||
me.mutateData(store, store.getRange());
|
||||
});
|
||||
|
||||
me.callParent(arguments);
|
||||
},
|
||||
|
||||
mutateData: function(store, records) {
|
||||
var view = this.getView(),
|
||||
arr = [],
|
||||
len = records.length,
|
||||
i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
arr.push({
|
||||
xtype: 'menuitem',
|
||||
uId: records[i].get('id'),
|
||||
text: records[i].get('name'),
|
||||
cls: 'font-icon ' + (records[i].get('online') ? 'online-user' : 'offline-user')
|
||||
});
|
||||
}
|
||||
|
||||
Ext.suspendLayouts();
|
||||
view.removeAll(true);
|
||||
view.add(arr);
|
||||
Ext.resumeLayouts(true);
|
||||
},
|
||||
|
||||
itemListClicked: function(menu, item) {
|
||||
var selectedUser = Ext.getStore('ChatList').findRecord('id', item.uId, 0, false, true, true);
|
||||
if (selectedUser && selectedUser.get('online'))
|
||||
this.fireEvent('openpmtab', null, selectedUser);
|
||||
}
|
||||
});
|
@ -0,0 +1,15 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatListModel', {
|
||||
extend: 'Ext.app.ViewModel',
|
||||
|
||||
alias: 'viewmodel.chatlist',
|
||||
|
||||
stores: {
|
||||
friends: {
|
||||
//Store reference
|
||||
type: 'chatlist',
|
||||
|
||||
//Auto load
|
||||
autoLoad: true
|
||||
}
|
||||
}
|
||||
});
|
@ -0,0 +1,11 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatModel', {
|
||||
extend: 'Ext.app.ViewModel',
|
||||
alias: 'viewmodel.chat',
|
||||
data: {
|
||||
new_message:''
|
||||
},
|
||||
formulas: {},
|
||||
stores: {
|
||||
notifications: 'Chat'
|
||||
}
|
||||
});
|
@ -0,0 +1,28 @@
|
||||
Ext.define('NgcpCsc.view.pages.chat.ChatNotifications', {
|
||||
extend: 'Ext.DataView',
|
||||
xtype: 'chat-notifications',
|
||||
|
||||
cls: 'user-notifications',
|
||||
|
||||
scrollable: false,
|
||||
|
||||
listeners: {
|
||||
itemclick: 'openPM'
|
||||
},
|
||||
|
||||
itemTpl: [
|
||||
"<div class='comments'>",
|
||||
"<img src='{thumbnail}' alt='' class='profile-icon'>",
|
||||
"<div class='content-wrap'>",
|
||||
"<div>",
|
||||
"<h4 class='profilenotifications-username'>{name}</h4>",
|
||||
"<span class='from-now'><span class='x-fa fa-clock-o'></span>{time} {date}",
|
||||
"<span class='like-comment-btn-wrap'>", // hide the private message button in case the message comes from the user (in this case _d = 0);
|
||||
"<button type='button' id='{name}' class='x-fa fa-comments {[values.name === 'administrator' ? 'hide-pm' : '']}'></button>",
|
||||
"</span></span>",
|
||||
"</div>",
|
||||
"<div class='content'>{content}</div>",
|
||||
"</div>",
|
||||
"</div>"
|
||||
]
|
||||
});
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
"data": [{
|
||||
"id": 840,
|
||||
"name": "Jil Sanchez",
|
||||
"date": "10/27/2016",
|
||||
"isActive": true,
|
||||
"time": "13:42",
|
||||
"thumbnail": "resources/images/user-profile/9.png",
|
||||
"content": "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don\'t look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn\'t anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc."
|
||||
}, {
|
||||
"id": 252,
|
||||
"name": "Ben Wright",
|
||||
"date": "10/27/2010",
|
||||
"isActive": true,
|
||||
"time": "14:03",
|
||||
"thumbnail": "resources/images/user-profile/10.png",
|
||||
"content": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry\'s standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
|
||||
}, {
|
||||
"id": 162,
|
||||
"name": "Allen Morris",
|
||||
"date": "10/27/2016",
|
||||
"isActive": true,
|
||||
"time": "4:57",
|
||||
"thumbnail": "resources/images/user-profile/11.png",
|
||||
"content": "There are many variations of passages of Lorem Ipsum available, but the majority have suffered alteration in some form, by injected humour, or randomised words which don\'t look even slightly believable. If you are going to use a passage of Lorem Ipsum, you need to be sure there isn\'t anything embarrassing hidden in the middle of text. All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as necessary, making this the first true generator on the Internet. It uses a dictionary of over 200 Latin words, combined with a handful of model sentence structures, to generate Lorem Ipsum which looks reasonable. The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc."
|
||||
}]
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
{
|
||||
"data": [{
|
||||
"id": 840,
|
||||
"online": true,
|
||||
"name": "Jil Sanchez"
|
||||
}, {
|
||||
"id": 1,
|
||||
"online": false,
|
||||
"name": "Oneill Franklin"
|
||||
}, {
|
||||
"id": 3,
|
||||
"online": false,
|
||||
"name": "Branch Allison"
|
||||
}, {
|
||||
"id": 252,
|
||||
"online": true,
|
||||
"name": "Ben Wright"
|
||||
}, {
|
||||
"id": 162,
|
||||
"online": true,
|
||||
"name": "Allen Morris"
|
||||
}, {
|
||||
"id": 5,
|
||||
"online": false,
|
||||
"name": "Suzette Powell"
|
||||
}]
|
||||
}
|
Loading…
Reference in new issue