Page MenuHomePhorge

D443.1774854681.diff
No OneTemporary

Authored By
Unknown
Size
16 KB
Referenced Files
None
Subscribers
None

D443.1774854681.diff

diff --git a/assets/js/api.js b/assets/js/api.js
--- a/assets/js/api.js
+++ b/assets/js/api.js
@@ -2,8 +2,10 @@
import {Socket, LongPoll, Presence} from "phoenix"
import UserListWidget from "./widgets/userlist"
import UserStatusWidget from "./widgets/userstatus"
+import ChannelListWidget from "./widgets/channellist"
import ChatInputWidget from "./widgets/chatinput"
import ChatRoomWidget from "./widgets/chatroom"
+import ChatDetailsWidget from "./widgets/chatdetails"
class KolabChat
{
@@ -16,6 +18,8 @@
* - userStatusElement: Id of HTML element where to put users status widget
* - chatInputElement: Id of HTML element which is a text chat input
* - chatRoomElement: Id of HTML element where to put text conversation
+ * - chatDetailsElement: Id of HTML element where to put chat room details widget
+ * - channelListElement: Id of HTML element where to put channellist widget
*/
constructor(config)
{
@@ -64,6 +68,7 @@
if (this.config.userListElement && $('#' + this.config.userListElement).length) {
config = {
username: this.username,
+ title: true,
openChat: (e, user) => { this.openChat(e, user) }
}
this.userListWidget = new UserListWidget(this.config.userListElement, config)
@@ -77,6 +82,23 @@
this.userStatusWidget = new UserStatusWidget(this.config.userStatusElement, config)
}
+ if (this.config.channelListElement && $('#' + this.config.channelListElement).length) {
+ config = {
+ username: this.username,
+ title: true,
+ openChat: (e, roomId) => { this.openExistingChat(roomId) },
+ createChat: (e) => { this.openChat(e); }
+ }
+ this.channelListWidget = new ChannelListWidget(this.config.channelListElement, config)
+ }
+
+ if (this.config.chatDetailsElement && $('#' + this.config.chatDetailsElement).length) {
+ config = {
+ submit: (e, data) => { this.updateChatDetails(data); }
+ }
+ this.chatDetailsWidget = new ChatDetailsWidget(this.config.chatDetailsElement, config)
+ }
+
if (this.config.chatRoomElement && $('#' + this.config.chatRoomElement).length) {
this.chatRoomWidget = new ChatRoomWidget(this.config.chatRoomElement)
}
@@ -139,6 +161,12 @@
})
}
+ if (this.chatDetailsWidget) {
+ this.chat.on("info", message => {
+ this.chatDetailsWidget.setRoom(message)
+ })
+ }
+
let join = this.chat.join()
if (invitees) {
@@ -231,7 +259,11 @@
openChat(event, user)
{
let windowName = 'KolabChat' + new Date().getTime()
- let url = "/chat/?token=" + encodeURIComponent(this.config.token) + "&invite=" + encodeURIComponent(user)
+ let url = "/chat/?token=" + encodeURIComponent(this.config.token)
+
+ if (user) {
+ url += "&invite=" + encodeURIComponent(user)
+ }
var extwin = window.open(url, windowName);
}
@@ -248,6 +280,14 @@
var extwin = window.open(url, windowName);
}
+ /**
+ * Update chat room details (e.g. name)
+ */
+ updateChatDetails(data)
+ {
+ // TODO
+ }
+
static extend(obj, src)
{
Object.keys(src).forEach(function(key) { obj[key] = src[key] })
diff --git a/assets/js/app.js b/assets/js/app.js
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -24,7 +24,9 @@
let chat = new KolabChat({
userListElement: "userlist",
userStatusElement: "userstatus",
+ channelListElement: "channellist",
chatRoomElement: "chat_txt",
+ chatDetailsElement: "chat_details",
chatInputElement: "chat_txt_input"
})
diff --git a/assets/js/widgets/channellist.js b/assets/js/widgets/channellist.js
new file mode 100644
--- /dev/null
+++ b/assets/js/widgets/channellist.js
@@ -0,0 +1,87 @@
+
+class ChannelListWidget
+{
+ /**
+ * Configuration:
+ * - username: Current user name
+ * - openChat: Callback for "Open" button
+ * - createChat: Callback for "Create" button
+ * - title: Enable list header with Create button
+ */
+ constructor(id, config)
+ {
+ this.config = config || {}
+ this.id = id
+ this.render([])
+ }
+
+ setUser(username, userId)
+ {
+ this.config.username = username
+ this.config.userId = userId
+ }
+
+
+ /**
+ * Render channels list
+ */
+ render(channels)
+ {
+ let title = ''
+ let btn = ''
+ let list = $('#' + this.id)
+ let config = this.config
+ let html = channels.map(channel => {
+ // TODO: List only public channels and channels the user has been invited to
+ let buttons = this.buttons(channel)
+ return `
+ <li class="list-group-item" data-channel="${channel.id}">
+ <span class="glyphicon glyphicon-channel"></span> #${channel.name}
+ ${buttons}
+ </li>`
+ })
+ .join("")
+
+ if (config.title === true) {
+ if (config.createChat) {
+ btn = `
+ <button type="button" class="btn btn-primary btn-xs" data-action="createChat">
+ <span class="glyphicon glyphicon-plus-sign"></span> Create
+ </button>
+ `
+ }
+
+ title = `<div class="channellist-head">Channels ${btn}</div>` // TODO: Localization
+ }
+
+ list.html(title + '<ul class="channellist list-group">' + html + '</ul>')
+
+ $('button', list).on('click', function(e) {
+ let action = $(this).data('action')
+ if (action && config[action]) {
+ config[action](e, $(this).parents('li').data('channel'))
+ }
+ })
+ }
+
+ /**
+ * Render channel list record buttons
+ */
+ buttons(channel)
+ {
+ let buttons = ''
+
+ if (this.config.openChat) {
+ let btn_name = '<span class="glyphicon glyphicon-comment"></span> Open' // TODO: localization
+ buttons += `<button type="button" class="btn btn-primary btn-xs" data-action="openChat">${btn_name}</button>`
+ }
+
+ if (buttons) {
+ buttons = '<div class="btn-group">' + buttons + '</div>'
+ }
+
+ return buttons
+ }
+}
+
+export default ChannelListWidget
diff --git a/assets/js/widgets/chatdetails.js b/assets/js/widgets/chatdetails.js
new file mode 100644
--- /dev/null
+++ b/assets/js/widgets/chatdetails.js
@@ -0,0 +1,51 @@
+
+class ChatDetailsWidget
+{
+ /**
+ * Configuration:
+ * - submit: Callback for chat details update (only name for now)
+ */
+ constructor(id, config)
+ {
+ this.config = config || {}
+ this.id = id
+ this.render()
+ }
+
+ /**
+ * Set chat room details and re-render the widget
+ */
+ setRoom(room)
+ {
+ this.render(room)
+ }
+
+ /**
+ * Renders text chat input widget
+ */
+ render(room)
+ {
+ if (!room || !room.id) {
+ return $('#' + this.id).html('')
+ }
+
+ // TODO: Localization
+
+ let room_name = room.name || '';
+ let html = `
+ <div>Room id: ${room.id}</div>
+ <div>Room name: <input name="chat_name" value="${room_name}" class="form-control" /></div>
+ `
+
+ $('#' + this.id)
+ .html(html)
+ .on('keypress', 'input', e => {
+ let txt
+ if (e.keyCode == 13 && this.config.submit && (txt = $(e.target).val())) {
+ this.config.submit(e, txt)
+ }
+ })
+ }
+}
+
+export default ChatDetailsWidget
diff --git a/assets/js/widgets/userlist.js b/assets/js/widgets/userlist.js
--- a/assets/js/widgets/userlist.js
+++ b/assets/js/widgets/userlist.js
@@ -4,12 +4,14 @@
/**
* Configuration:
* - username: Current user name
- * - openChat: callback for "Open chat" button
+ * - openChat: Callback for "Open chat" button
+ * - title: Enables list header
*/
constructor(id, config)
{
this.config = config || {}
this.id = id
+ this.render([])
}
setUser(username, userId)
@@ -24,6 +26,7 @@
*/
render(presences)
{
+ let title = ''
let list = $('#' + this.id)
let config = this.config
let html = presences.map(presence => {
@@ -38,7 +41,11 @@
})
.join("")
- list.html(html)
+ if (config.title === true) {
+ title = '<div class="userlist-head">Users</div>' // TODO: Localization
+ }
+
+ list.html(title + '<ul class="userlist list-group">' + html + '</ul>')
$('button', list).on('click', function(e) {
let action = $(this).data('action')
@@ -56,7 +63,7 @@
let buttons = ''
if (this.config.openChat) {
- let btn_name = '<span class="glyphicon glyphicon-comment"></span> Open chat'
+ let btn_name = '<span class="glyphicon glyphicon-comment"></span> Open chat' // TODO: Localization
buttons += `<button type="button" class="btn btn-primary btn-xs" data-action="openChat">${btn_name}</button>`
}
diff --git a/assets/js/widgets/userstatus.js b/assets/js/widgets/userstatus.js
--- a/assets/js/widgets/userstatus.js
+++ b/assets/js/widgets/userstatus.js
@@ -22,6 +22,8 @@
"invisible",
"offline"
];
+
+ // TODO: render() with defalt state here
}
/**
diff --git a/lib/kolab_chat/web/channels/room_channel.ex b/lib/kolab_chat/web/channels/room_channel.ex
--- a/lib/kolab_chat/web/channels/room_channel.ex
+++ b/lib/kolab_chat/web/channels/room_channel.ex
@@ -5,6 +5,8 @@
@spec join(topic :: binary(), args :: map(), socket :: pid()) :: {:ok, socket :: pid()}
def join("room:" <> room_name, _, socket) do
+ socket = assign(socket, :room, %{id: room_name})
+ send self(), :after_join
{:ok, socket}
end
@@ -27,4 +29,11 @@
def handle_in("ctl:invite", params, socket) do
{:noreply, socket}
end
+
+ @spec handle_info(:after_join, socket :: pid()) :: {:noreply, socket :: pid()}
+ def handle_info(:after_join, socket) do
+ push socket, "info", socket.assigns.room
+ {:noreply, socket}
+ end
+
end
diff --git a/lib/kolab_chat/web/templates/chat/index.html.eex b/lib/kolab_chat/web/templates/chat/index.html.eex
--- a/lib/kolab_chat/web/templates/chat/index.html.eex
+++ b/lib/kolab_chat/web/templates/chat/index.html.eex
@@ -1,3 +1,3 @@
-Room id is: <%= @room %>
+<div id="chat_details"></div>
<div id="chat_txt" class="textchat"></div>
<div id="chat_txt_input" class="textchatinput input-group"></div>
diff --git a/lib/kolab_chat/web/templates/page/index.html.eex b/lib/kolab_chat/web/templates/page/index.html.eex
--- a/lib/kolab_chat/web/templates/page/index.html.eex
+++ b/lib/kolab_chat/web/templates/page/index.html.eex
@@ -1,7 +1,7 @@
<div class="jumbotron">
<%= if @conn.assigns[:user] do %>
- Users List:
- <ul id="userlist" class="userlist list-group"></ul>
+ <div id="userlist"></div>
+ <div id="channellist"></div>
<% else %>
<h2><%= gettext "Welcome to %{name}", name: "Kolab Chat!" %></h2>
<p class="lead"><%= gettext "Real-time communication for the Kolab groupware system." %></p>
diff --git a/mix.lock b/mix.lock
--- a/mix.lock
+++ b/mix.lock
@@ -1,18 +1,18 @@
-%{"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [:mix], [{:exquisite, "~> 0.1.7", [hex: :exquisite, repo: "hexpm", optional: false]}], "hexpm"},
- "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm"},
- "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
- "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [], [], "hexpm"},
- "credo": {:hex, :credo, "0.7.4", "0c33bcce4d574ce6df163cbc7d1ecb22de65713184355bd3be81cc4ab0ecaafa", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}], "hexpm"},
- "exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [], [], "hexpm"},
- "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [], [], "hexpm"},
- "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [], [], "hexpm"},
- "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], [], "hexpm"},
- "phoenix": {:hex, :phoenix, "1.3.0-rc.2", "53104ada25ba85fe160268c0dc826fe038bc074293730b4522fb9aca28d8aa13", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"},
- "phoenix_html": {:hex, :phoenix_html, "2.9.3", "1b5a2122cbf743aa242f54dced8a4f1cc778b8bd304f4b4c0043a6250c58e258", [], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
- "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.8", "4333f9c74190f485a74866beff2f9304f069d53f047f5fbb0fb8d1ee4c495f73", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm"},
- "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.1", "c10ddf6237007c804bf2b8f3c4d5b99009b42eca3a0dfac04ea2d8001186056a", [], [], "hexpm"},
- "plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}], "hexpm"},
- "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
- "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"},
- "remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], [], "hexpm"},
- "uuid": {:hex, :uuid, "1.1.7", "007afd58273bc0bc7f849c3bdc763e2f8124e83b957e515368c498b641f7ab69", [:mix], [], "hexpm"}}
+%{"amnesia": {:hex, :amnesia, "0.2.7", "ffc2221bf72da4cfafbbb497adf9cf7e52138f1333cec5836187a53f94ae0665", [:mix], [{:exquisite, "~> 0.1.7", [hex: :exquisite, optional: false]}]},
+ "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], []},
+ "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]},
+ "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
+ "credo": {:hex, :credo, "0.7.4", "0c33bcce4d574ce6df163cbc7d1ecb22de65713184355bd3be81cc4ab0ecaafa", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, optional: false]}]},
+ "exquisite": {:hex, :exquisite, "0.1.8", "ee8f56aae477287ce5e7dfcbc163a420cccbb73e680a6d80a09203e9ef514fa4", [:mix], []},
+ "fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
+ "gettext": {:hex, :gettext, "0.13.1", "5e0daf4e7636d771c4c71ad5f3f53ba09a9ae5c250e1ab9c42ba9edccc476263", [:mix], []},
+ "mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
+ "phoenix": {:hex, :phoenix, "1.3.0-rc.2", "53104ada25ba85fe160268c0dc826fe038bc074293730b4522fb9aca28d8aa13", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:phoenix_pubsub, "~> 1.0", [hex: :phoenix_pubsub, optional: false]}, {:plug, "~> 1.3.2 or ~> 1.4", [hex: :plug, optional: false]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, optional: false]}]},
+ "phoenix_html": {:hex, :phoenix_html, "2.9.3", "1b5a2122cbf743aa242f54dced8a4f1cc778b8bd304f4b4c0043a6250c58e258", [:mix], [{:plug, "~> 1.0", [hex: :plug, optional: false]}]},
+ "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.0.8", "4333f9c74190f485a74866beff2f9304f069d53f047f5fbb0fb8d1ee4c495f73", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, optional: false]}, {:phoenix, "~> 1.0 or ~> 1.2-rc", [hex: :phoenix, optional: false]}]},
+ "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.0.1", "c10ddf6237007c804bf2b8f3c4d5b99009b42eca3a0dfac04ea2d8001186056a", [:mix], []},
+ "plug": {:hex, :plug, "1.3.5", "7503bfcd7091df2a9761ef8cecea666d1f2cc454cbbaf0afa0b6e259203b7031", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
+ "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
+ "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []},
+ "remix": {:hex, :remix, "0.0.2", "f06115659d8ede8d725fae1708920ef73353a1b39efe6a232d2a38b1f2902109", [:mix], []},
+ "uuid": {:hex, :uuid, "1.1.7", "007afd58273bc0bc7f849c3bdc763e2f8124e83b957e515368c498b641f7ab69", [:mix], []}}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 7:11 AM (3 d, 21 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18795498
Default Alt Text
D443.1774854681.diff (16 KB)

Event Timeline