Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
U
ulakbus-ui
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ulakbus
ulakbus-ui
Commits
d6b81cee
Commit
d6b81cee
authored
Jul 20, 2016
by
Vladimir Baranov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rref #5392. Add popup dialogs, add basic send message funtionality
parent
e48eee72
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
303 additions
and
124 deletions
+303
-124
messaging.js
app/components/messaging/messaging.js
+92
-6
messaging_forms.js
app/components/messaging/messaging_forms.js
+0
-39
messaging_service.js
app/components/messaging/messaging_service.js
+59
-4
add_user_unit.html
app/components/messaging/templates/add_user_unit.html
+7
-0
conversation.html
app/components/messaging/templates/conversation.html
+85
-0
create_channel.html
app/components/messaging/templates/create_channel.html
+9
-0
delete_confirmation.html
app/components/messaging/templates/delete_confirmation.html
+9
-0
index.html
app/components/messaging/templates/index.html
+6
-61
search_user.html
app/components/messaging/templates/search_user.html
+3
-3
directives.js
app/shared/directives.js
+33
-11
No files found.
app/components/messaging/messaging.js
View file @
d6b81cee
angular
.
module
(
"ulakbus.messaging"
)
.
directive
(
'messaging'
,
function
(
Generator
,
MessagingService
,
$log
,
$rootScope
)
{
.
directive
(
'messaging'
,
function
(
Generator
,
MessagingService
,
$log
,
$rootScope
,
MessagingPopup
)
{
function
getKey
(
channel
)
{
var
channelKey
=
channel
.
channel_key
;
if
(
channel
.
hasOwnProperty
(
'key'
)){
channelKey
=
channel
.
key
;
// direct channel
}
return
channelKey
;
}
return
{
templateUrl
:
'components/messaging/templates/index.html'
,
restrict
:
'E'
,
replace
:
true
,
scope
:
{},
link
:
function
(
iScope
,
iElem
,
iAttrs
){
var
popupRootElement
=
$
(
iElem
).
find
(
'.popup-placeholder'
);
iScope
.
deleteConfirmation
=
function
(){
return
MessagingPopup
.
show
({
templateUrl
:
"components/messaging/templates/delete_confirmation.html"
,
rootElement
:
popupRootElement
})
};
iScope
.
searchUser
=
function
(){
MessagingPopup
.
show
({
templateUrl
:
"components/messaging/templates/search_user.html"
,
rootElement
:
popupRootElement
,
link
:
function
(
scope
){
scope
.
onChange
=
function
(
query
){
scope
.
loading
=
true
;
scope
.
searchResult
=
[];
MessagingService
.
search_user
(
query
)
.
then
(
function
(
users
){
scope
.
searchResult
=
users
;
})
.
finally
(
function
(){
scope
.
loading
=
false
;
})
};
scope
.
onChange
(
""
);
}
}).
then
(
function
(
user
){
return
iScope
.
createDirectChannel
(
user
);
});
};
iScope
.
createChannel
=
function
(){
MessagingPopup
.
show
({
templateUrl
:
"components/messaging/templates/create_channel.html"
,
rootElement
:
popupRootElement
,
link
:
function
(
scope
){
scope
.
channel
=
{};
}
}).
then
(
function
(
channel
){
return
MessagingService
.
create_channel
(
channel
.
name
,
channel
.
description
);
});
};
},
controller
:
function
(
$scope
)
{
$scope
.
hidden
=
false
;
$scope
.
showSearch
=
{
user
:
false
};
// shared object to populate models through scopes
$scope
.
shared
=
{};
MessagingService
.
list_channels
().
then
(
function
(
groupedChannels
)
{
$scope
.
publicChannels
=
groupedChannels
[
MessagingService
.
CHANNEL_TYPE
.
PUBLIC
];
...
...
@@ -25,18 +80,49 @@ angular.module("ulakbus.messaging")
var
key
=
user
[
1
];
MessagingService
.
create_direct_channel
(
key
)
.
then
(
function
(
result
){
$log
.
info
(
"Channel for user "
,
user
[
0
],
"created: "
,
result
);
return
selectChannel
(
result
.
channel_key
);
});
};
$scope
.
createDirectChannel
=
this
.
createDirectChannel
;
$scope
.
hideApp
=
function
(){
$scope
.
hidden
=
true
;
};
function
selectChannel
(
channelKey
){
$scope
.
loadingChannel
=
true
;
return
MessagingService
.
show_channel
(
channelKey
).
then
(
function
(
result
){
return
result
;
}).
finally
(
function
(){
$scope
.
loadingChannel
=
false
;
})
}
$scope
.
selectChannel
=
function
(
channel
){
$scope
.
activeChannel
=
channel
;
var
channelKey
=
getKey
(
channel
);
$scope
.
selectedChannel
=
channel
;
selectChannel
(
channelKey
).
then
(
function
(
result
){
channel
.
messages
=
result
.
last_messages
;
});
}
$scope
.
sendMessage
=
function
(
content
){
if
(
!
content
)
return
;
var
channelKey
=
getKey
(
$scope
.
selectedChannel
);
// select message type: 2 - direct message, 4 - channel message;
var
msgType
=
$scope
.
selectedChannel
.
type
==
MessagingService
.
CHANNEL_TYPE
.
DIRECT
?
2
:
4
;
MessagingService
.
create_message
(
channelKey
,
msgType
,
content
).
then
(
function
(
result
){
$scope
.
shared
.
message
=
""
;
});
}
}
};
})
.
filter
(
'fromNow'
,
function
(
Moment
){
return
function
(
datetime
){
return
Moment
(
datetime
).
fromNow
();
}
});
app/components/messaging/messaging_forms.js
View file @
d6b81cee
angular
.
module
(
"ulakbus.messaging"
)
.
directive
(
"messagingSearchUser"
,
function
(
MessagingService
,
$log
){
return
{
templateUrl
:
"components/messaging/templates/search_user.html"
,
restrict
:
'E'
,
replace
:
true
,
require
:
"^messaging"
,
scope
:
{
'showSearch'
:
'=ngShow'
},
link
:
function
(
iScope
,
iElem
,
iAttrs
,
messagingCtrl
){
iScope
.
selectUser
=
function
(
user
){
messagingCtrl
.
createDirectChannel
(
user
);
iScope
.
hide
();
}
},
controller
:
function
(
$scope
){
$scope
.
searchResult
=
[];
$scope
.
hide
=
function
(){
$scope
.
showSearch
=
false
;
$scope
.
searchResult
=
[];
}
function
search
(
query
){
$scope
.
loading
=
true
;
$scope
.
searchResult
=
[];
MessagingService
.
search_user
(
query
)
.
then
(
function
(
users
){
$scope
.
searchResult
=
users
;
})
.
finally
(
function
(){
$scope
.
loading
=
false
;
})
}
$scope
.
onChange
=
function
(
query
){
search
(
query
);
};
}
}
})
app/components/messaging/messaging_service.js
View file @
d6b81cee
...
...
@@ -44,6 +44,16 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
})
}
// prepare messages for UI
function
prepareMessages
(
messages
){
for
(
var
i
=
0
;
i
<
messages
.
length
;
i
++
){
var
message
=
messages
[
i
];
// FIXME: process timezone properly
var
ts
=
message
.
timestamp
.
replace
(
/
\.
0+Z$/
,
""
);
message
.
moment
=
Moment
(
ts
);
}
}
msg
.
list_channels
=
function
list_channels
(){
/**
* request channels list as below;
...
...
@@ -194,6 +204,7 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
};
return
wsRequest
(
outgoing
).
then
(
function
(
result
){
$log
.
info
(
"Show channel "
,
channelKey
,
": "
,
result
);
prepareMessages
(
result
.
last_messages
);
return
result
;
})
};
...
...
@@ -225,10 +236,14 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
msg
.
create_message
=
function
(
channelKey
,
msgType
,
body
,
attachments
){
var
outgoing
=
{
view
:
'_zops_create_message'
,
channel
:
channelKey
,
type
:
msgType
,
body
:
body
,
attachments
:
attachments
message
:
{
channel
:
channelKey
,
type
:
msgType
,
title
:
""
,
receiver
:
""
,
body
:
body
,
attachments
:
attachments
}
};
return
wsRequest
(
outgoing
).
then
(
function
(
result
){
...
...
@@ -334,4 +349,44 @@ angular.module('ulakbus.messaging', ['ui.bootstrap'])
}
return
msg
;
})
.
service
(
"MessagingPopup"
,
function
(
$q
,
$compile
,
$http
,
$rootScope
){
function
compile
(
template
,
config
){
var
resultDeferred
=
$q
.
defer
();
var
scope
=
config
.
scope
||
$rootScope
.
$new
(
true
);
var
rootElement
=
config
.
rootElement
;
var
element
=
$compile
(
template
)(
scope
);
if
(
config
.
link
){
config
.
link
(
scope
);
}
scope
.
done
=
function
(
result
){
resultDeferred
.
resolve
.
apply
(
this
,
arguments
);
};
scope
.
cancel
=
function
(){
resultDeferred
.
reject
.
apply
(
this
,
arguments
);
};
rootElement
.
empty
();
rootElement
.
append
(
element
);
resultDeferred
.
promise
.
_done
=
scope
.
done
;
resultDeferred
.
promise
.
_cancel
=
scope
.
cancel
;
return
resultDeferred
.
promise
.
finally
(
function
(){
rootElement
.
empty
();
scope
.
$destroy
();
});
}
this
.
show
=
function
(
config
){
if
(
config
.
templateUrl
){
return
$http
({
method
:
'GET'
,
url
:
config
.
templateUrl
,
cache
:
true
}).
then
(
function
(
result
){
return
compile
(
result
.
data
,
config
)
});
}
return
compile
(
config
.
template
,
config
);
};
});
app/components/messaging/templates/add_user_unit.html
0 → 100644
View file @
d6b81cee
<div
class=
"chat-popup-window add-user-unit"
style=
"display:block;"
>
<div
class=
"close-chat-popup-window"
><span
class=
"glyphicon glyphicon-remove"
></span></div>
<h3>
Add User/Unit
</h3>
<div
class=
"text-center"
>
<input
type=
"text"
placeholder=
"Search User/Unit to Add"
><br>
</div>
</div>
app/components/messaging/templates/conversation.html
0 → 100644
View file @
d6b81cee
<span
class=
"loader"
ng-show=
"loadingChannel"
></span>
<div
class=
"conversation-section"
ng-hide=
"selectedChannel"
>
<div
class=
"conversation-body"
>
<div
class=
"conversation-body-inner"
>
<div
class=
"beginning-of-conversation"
>
Select or create channel to begin conversation
</div>
</div>
</div>
</div>
<div
class=
"conversation-section"
ng-hide=
"loadingChannel || !selectedChannel"
>
<div
class=
"conversation-header"
>
<div
class=
"conversation-user"
>
<div
class=
"user-photo"
ng-show=
"selectedChannel.avatar_url"
><img
ng-src=
"{{selectedChannel.avatar_url}}"
></div>
<div
class=
"user-name"
>
{{selectedChannel.name}}
</div>
</div>
<div
class=
"conversation-search"
>
<input
type=
"text"
placeholder=
"Arama Yap"
>
</div>
<div
class=
"dropdown"
>
<div
class=
"chat-app-actions dropdown-toggle"
data-toggle=
"dropdown"
id=
"chat-app-actions"
>
<span
class=
"glyphicon glyphicon-option-vertical"
></span>
</div>
<ul
class=
"dropdown-menu"
ng-show=
"selectedChannel.actions.length > 0"
aria-labelledby=
"chat-app-actions"
style=
"left: inherit; top: 53px; right: 66px;"
>
<li><a
ng-click=
"applyChannelAction(action)"
ng-repeat=
"action in selectedChannel.actions"
>
{{action[0]}}
</a></li>
</ul>
</div>
<div
class=
"close-chat-app"
>
<span
class=
"glyphicon glyphicon-remove"
ng-click=
"hideApp()"
></span>
</div>
</div>
<div
class=
"conversation-body"
>
<div
class=
"conversation-body-inner"
>
<div
class=
"beginning-of-conversation"
>
This is the beginning of the conversation
</div>
<div
class=
"conversation-block clearfix"
ng-repeat=
"msg in selectedChannel.messages"
>
<div
class=
"conversation-actions"
>
<div
class=
"action"
><span
class=
"glyphicon glyphicon-star-empty"
></span></div>
<div
class=
"action dropdown-toggle"
data-toggle=
"dropdown"
>
<span
class=
"glyphicon glyphicon-option-horizontal"
></span>
</div>
<ul
class=
"dropdown-menu"
style=
"left:-86px;"
>
<li><a
href=
"#"
>
Edit
</a></li>
<li><a
href=
"#"
ng-click=
"deleteConfirmation()"
>
Delete
</a></li>
</ul>
</div>
<div
class=
"user-photo"
>
<img
src=
"../../../img/erkan.jpg"
>
</div>
<div
class=
"user-message"
>
<div
class=
"message-header clearfix"
>
<div
class=
"user-name"
>
{{::msg.sender_name}}
</div>
<div
class=
"message-time"
>
{{::msg.moment|fromNow}}
</div>
</div>
<div
class=
"message-content"
>
{{::msg.content}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"conversation-footer"
>
<textarea
placeholder=
"Mesajını buraya yaz..."
ng-model=
"shared.message"
on-enter-pressed=
"sendMessage(shared.message)"
></textarea>
<div
class=
"add-attachment"
>
<span
class=
"glyphicon glyphicon-send"
ng-click=
"sendMessage(shared.message);"
></span>
<div
class=
"dropup"
style=
"float:left;"
>
<span
class=
"glyphicon glyphicon-paperclip dropdown-toggle"
data-toggle=
"dropdown"
id=
"attachment"
></span>
<ul
class=
"dropdown-menu"
aria-labelledby=
"attachment"
style=
"left:-104px;"
>
<li><a
href=
"#"
>
Image
</a></li>
<li><a
href=
"#"
>
File
</a></li>
</ul>
</div>
</div>
</div>
</div>
app/components/messaging/templates/create_channel.html
0 → 100644
View file @
d6b81cee
<div
class=
"chat-popup-window create-new-channel-window"
>
<div
class=
"close-chat-popup-window"
ng-click=
"cancel()"
><span
class=
"glyphicon glyphicon-remove"
></span></div>
<h3>
Create New Channel
</h3>
<div
class=
"text-center"
>
<input
type=
"text"
placeholder=
"Channel Name"
ng-model=
"channel.name"
><br>
<textarea
placeholder=
"Channel Description"
ng-model=
"channel.description"
></textarea>
<button
class=
"btn btn-success"
ng-click=
"done(channel)"
>
Create
</button>
</div>
</div>
app/components/messaging/templates/delete_confirmation.html
0 → 100644
View file @
d6b81cee
<div
class=
"chat-popup-window confirmation-window"
>
<div
class=
"close-chat-popup-window"
ng-click=
"cancel()"
><span
class=
"glyphicon glyphicon-remove"
></span></div>
<div
class=
"text-center"
style=
"margin-top: 150px;font-size: 26px;"
>
<p>
Are you sure you want to delete?
</p>
<button
class=
"btn btn-success"
style=
"font-size: 20px;"
ng-click=
"done()"
>
Yes
</button>
<button
class=
"btn btn-default"
style=
"font-size: 20px;"
ng-click=
"cancel()"
>
Cancel
</button>
</div>
</div>
app/components/messaging/templates/index.html
View file @
d6b81cee
...
...
@@ -10,75 +10,20 @@
</ul>
<ul
class=
"channels"
>
<li
class=
"title"
>
CHANNELS
<span
class=
"add-action glyphicon glyphicon-plus-sign"
></span></li>
<li
class=
"notification"
ng-repeat=
"ch in publicChannels
"
>
{{ch.name}}
</li>
<li
class=
"title"
>
CHANNELS
<span
class=
"add-action glyphicon glyphicon-plus-sign"
ng-click=
"createChannel()"
></span></li>
<li
ng-class=
"{'notification': ch.unread, 'active': selectedChannel == ch}"
ng-repeat=
"ch in publicChannels"
ng-click=
"selectChannel(ch)
"
>
{{ch.name}}
</li>
</ul>
<ul
class=
"direct-messages"
>
<li
class=
"title"
>
DIRECT MESSAGES
<span
class=
"add-action glyphicon glyphicon-plus-sign"
ng-click=
"s
howSearch.user = true
"
></span></li>
<li
ng-class=
"{'notification': userChannel.unread
}"
ng-repeat=
"userChannel in directChannels
"
>
{{userChannel.name}}
</li>
<li
class=
"title"
>
DIRECT MESSAGES
<span
class=
"add-action glyphicon glyphicon-plus-sign"
ng-click=
"s
earchUser()
"
></span></li>
<li
ng-class=
"{'notification': userChannel.unread
, 'active': selectedChannel == userChannel}"
ng-repeat=
"userChannel in directChannels"
ng-click=
"selectChannel(userChannel)
"
>
{{userChannel.name}}
</li>
</ul>
</div>
<
div
class=
"conversation-section"
>
<
ng-include
src=
"'components/messaging/templates/conversation.html'"
></ng-include
>
<div
class=
"conversation-header"
>
<div
class=
"conversation-user"
>
<div
class=
"user-photo"
><img
src=
"../../../img/erkan.jpg"
></div>
<div
class=
"user-name"
>
Erkan Öğümsöğütlü
</div>
</div>
<div
class=
"conversation-search"
>
<input
type=
"text"
placeholder=
"Arama Yap"
>
</div>
<div
class=
"close-chat-app"
ng-click=
"hideApp()"
>
<span
class=
"glyphicon glyphicon-remove"
></span>
</div>
</div>
<div
class=
"conversation-body"
>
<div
class=
"conversation-body-inner"
>
<div
class=
"beginning-of-conversation"
>
This is the beginning of the conversation
</div>
<div
class=
"conversation-block clearfix"
>
<div
class=
"conversation-actions"
>
<div
class=
"action"
>
Edit
</div>
<div
class=
"action"
>
Delete
</div>
</div>
<div
class=
"user-photo"
>
<img
src=
"../../../img/erkan.jpg"
>
</div>
<div
class=
"user-message"
>
<div
class=
"message-header clearfix"
>
<div
class=
"user-name"
>
Erkan Öğümsöğütlü
</div>
<div
class=
"message-time"
>
13:16
</div>
</div>
<div
class=
"message-content"
>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer purus mauris.
</div>
</div>
</div>
</div>
</div>
<div
class=
"conversation-footer"
>
<textarea
placeholder=
"Mesajını buraya yaz..."
></textarea>
<div
class=
"add-attachment"
>
<span
class=
"glyphicon glyphicon-file"
></span>
<span
class=
"glyphicon glyphicon-picture"
></span>
</div>
</div>
</div>
<messaging-search-user
ng-show=
"showSearch.user"
></messaging-search-user>
<div
class=
"popup-placeholder"
></div>
</div>
</div>
...
...
app/components/messaging/templates/search_user.html
View file @
d6b81cee
<div
class=
"create-new-message-window"
>
<div
class=
"close-c
reate-new-message-window"
ng-click=
"hide
()"
><span
class=
"glyphicon glyphicon-remove"
></span></div>
<div
class=
"c
hat-popup-window c
reate-new-message-window"
>
<div
class=
"close-c
hat-popup-window"
ng-click=
"cancel
()"
><span
class=
"glyphicon glyphicon-remove"
></span></div>
<input
type=
"text"
placeholder=
"Birini ismi ile ara..."
ng-model=
"query"
ng-change=
"onChange(query)"
>
<div
class=
"search-results"
>
<span
class=
"loader"
ng-show=
"loading"
></span>
<div
class=
"user"
ng-repeat=
"user in searchResult"
ng-click=
"
selectUser
(user)"
>
<div
class=
"user"
ng-repeat=
"user in searchResult"
ng-click=
"
done
(user)"
>
<img
ng-src=
"{{user[2]}}"
ng-show=
"user[2]"
>
<div
class=
"user-name"
>
{{user[0]}}
</div>
</div>
...
...
app/shared/directives.js
View file @
d6b81cee
...
...
@@ -663,19 +663,20 @@ angular.module('ulakbus')
}
}
})
.
directive
(
'timetableActionSelector'
,
function
(
$timeout
){
.
directive
(
'timetableActionSelector'
,
function
(
$timeout
)
{
// Display/hide popover with actions
// global listener used to close popover when user clicks outside of the popover
$
(
'html'
).
on
(
'click'
,
function
(
e
)
{
$
(
'html'
).
on
(
'click'
,
function
(
e
)
{
var
target
=
$
(
e
.
target
);
if
(
target
.
parents
().
is
(
'.action-selector'
)){
if
(
target
.
parents
().
is
(
'.action-selector'
))
{
target
.
parents
(
'.action-selector'
).
children
(
'.popover'
).
toggleClass
(
'ng-hide'
);
return
;
}
if
(
target
.
hasClass
(
'action-selector'
)){
if
(
target
.
hasClass
(
'action-selector'
))
{
target
.
children
(
'.popover'
).
toggleClass
(
'ng-hide'
);
return
;
};
}
;
$
(
'.course-prg-scheduler .action-selector>.popover'
).
toggleClass
(
'ng-hide'
,
true
);
});
...
...
@@ -685,29 +686,29 @@ angular.module('ulakbus')
externalModel
:
'=ngModel'
,
onChange
:
"&ngChange"
},
link
:
function
(
iScope
,
iElem
,
iAttrs
)
{
link
:
function
(
iScope
,
iElem
,
iAttrs
)
{
var
valueToClassMap
=
{
1
:
'action-indicator_appropriate'
,
2
:
'action-indicator_uncertain'
,
3
:
'action-indicator_busy'
};
if
(
iAttrs
.
hasOwnProperty
(
'readonly'
)){
iAttrs
.
$observe
(
'readonly'
,
function
(
v
)
{
if
(
iAttrs
.
hasOwnProperty
(
'readonly'
))
{
iAttrs
.
$observe
(
'readonly'
,
function
(
v
)
{
if
(
v
&&
v
==
'false'
)
v
=
false
;
iScope
.
readonly
=
v
;
});
}
iScope
.
$watch
(
'externalModel'
,
function
(
value
)
{
iScope
.
$watch
(
'externalModel'
,
function
(
value
)
{
iScope
.
value
=
valueToClassMap
[
value
];
});
iScope
.
setModelValue
=
function
(
value
)
{
iScope
.
setModelValue
=
function
(
value
)
{
var
oldValue
=
iScope
.
externalModel
;
iScope
.
externalModel
=
value
;
// call change in next digest
$timeout
(
function
()
{
$timeout
(
function
()
{
if
(
iScope
.
onChange
&&
value
!=
oldValue
)
{
iScope
.
onChange
();
}
...
...
@@ -716,4 +717,25 @@ angular.module('ulakbus')
}
}
}
})
/**
* @memberof ulakbus
* @ngdoc directive
* @name onEnterPressed
* @description Fire action when enter pressed on element
*/
.
directive
(
"onEnterPressed"
,
function
()
{
return
{
link
:
function
(
scope
,
element
,
attrs
)
{
element
.
bind
(
"keydown keypress"
,
function
(
event
)
{
if
(
event
.
which
===
13
&&
!
event
.
ctrlKey
)
{
scope
.
$apply
(
function
(){
scope
.
$eval
(
attrs
.
onEnterPressed
);
});
event
.
preventDefault
();
}
})
}
}
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment