Clients use the regular joinRoom/-Call API and get a Nextcloud session
id. No special handling for sessions from the standalone signaling
server are required.
The signaling server regularly "pings" active sessions to prevent them
from timing out (in case of guest users).
Signed-off-by: Joachim Bauch <bauch@struktur.de>
When using the oldest to newest layout now the first (oldest) message
always shows the date.
When using the newest to oldest layout, however, there is no date shown
in the first (newest) message; in this case it would be good to show it
only if the newest message was not sent today, but the newest to oldest
layout is currently not used anywhere (and it is likely to be removed
from the code), so there was no need to spend time on that.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When the chat messages are shown from newest to oldest and a new message
arrives the list is automatically scrolled to keep the current visible
messages at the same place, except if the list was at the top, in which
case no scrolling is made and the new message appears.
When the chat messages are shown from oldest to newest and a new message
arrives the list is automatically scrolled to show the new message,
except if the list was not at the bottom in which case no scrolling is
made and the current visible messages are kept at the same place.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Before chat messages were shown from newest to oldest, with the new
message input above the list of messages. Now the layout can be chosen,
either the previous one or the reversed one, from oldest to newest with
the new message input below the list of messages.
The new reversed layout is the default one, and probably the old one
will not be used anywhere in the future... but for the time being I kept
the old one too just in case.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Limiting the scroll bar in the sidebar to the list of chat messages
causes the scroll bar to be removed from the whole sidebar in other tabs
too. Therefore, the scroll bars must be explicitly enabled in the other
tab contents that need them.
The list of participants grows dynamically, so a vertical scroll bar
should be enabled on it to be able to view all the participants in a
long list.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The positioning context (the element that an absolute element is
relative to) of the tooltips shown for the date of messages was the
author row, and thus they were visible only were the author row would be
visible. The author row would be clipped outside the list of messages
(due to its "overflow-y" CSS property), so the tooltip shown for the
date of the newest message was clipped at the top of the list of
messages.
Now the tooltips are added to the chat view itself, so "#app-content"
becomes their positioning context and thus are no longer clipped by the
list of messages.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
In CSS it is not currently possible to select an element based on
whether it has certain child or not, nor select the parent element of
another one. In certain cases it may be necessary to use a special style
for the tab content wrapper element, for example to remove the padding
from the wrapper and left the tab content element itself to handle it.
To support that now the tab content wrapper has the "tab-{tabId}" CSS
class in addition to the "tab" CSS class.
Another option would have been to make possible to specify the class
name to use when a tab was added so the same class could be used by the
wrapper when showing different tabs. However this seem like an uncommon
use case, and there should not be a lot of tabs anyway, so the current
approach would not require a lot of ".tab-{tabId1}", ".tab-{tabId2}",
".tab-{tabId3}"... selectors for the same rules in the CSS files anyway.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The class was copied from the markup of the server sidebar, but it is
not used anywhere and its name is misleading now that the scroll bar is
shown on the tabs that need it.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The value of the input was not properly updated when the model attribute
changed. Instead of updating it in that case too now it is always
updated before the input element is shown.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Some browsers (like Firefox) automatically return the focus to the new
message input after sending a message, while others (like Chromium) do
not. Now the focus is explicitly given back to the new message input to
make more comfortable to keep writing new messages.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
By default, "tooltip()" adds the tooltip element to the element in which
the function is called. If a "container" option is provided the tooltip
is added instead to the given element, although visually it will be
shown for the element in which the function is called.
The positioning context (the element that an absolute element is
relative to) of the tooltips shown for the date of messages was the
author row, and thus they were visible only were the author row would be
visible. The author row would be clipped outside the list of messages
(due to its "overflow-y" CSS property), so the tooltip shown for the
date of the newest message was clipped at the top of the list of
messages.
Now the ChatView provides a method to specify to which element append
the tooltip elements, so they can be appended to another element that
does not cause clipping problems.
Although right now it would be enough to add the tooltips to the chat
view itself, once the chat view layout is modified to show the input
field at the bottom then the same problem would arise when the chat view
is shown as the main view, as the tooltips would be clipped by
"#app-content". Thus, to be prepared for that change, they are added to
"#app" instead.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The "tab" CSS class does not apply when the chat view is shown in the
main view, and it is not needed either when shown in the sidebar, as it
is automatically set in the div to which the view is appended (in fact,
it was a bug, as two "tab" classes were nested and thus its padding was
duplicated).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When shown as the main view, the input field to add a new message is
always shown and a scroll bar is provided just for the list of messages.
Only the chat view is added and removed to and from the main view; the
other elements in the main view are not modified when that happens, and
they are hidden using some CSS magic.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Note that this only makes ChatView to inherit from Marionette.View, but
it does not make ChatView use all the fancy features of Marionette
Views.
This will be needed for proper View lifecycle support when the ChatView
is added and removed to and from the sidebar.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The TURN server values are now (tried to be) saved when the protocols
are changed, like it is done when the server URL or the secret are
changed.
Fixes#531
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The name of the room is removed by setting it to the empty string, but
the if condition was wrong and thus an empty string did not satisfy it.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Below certain window width the sidebar starts overlapping with the
content area, so the sidebar is automatically open only if it will not
overlap with the content.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The timestamp is in seconds, so when sent extremely fast two or more
messages can have the same timestamp. As a stable sorting algorithm is
used and the messages were sorted only by timestamp, when two or more
messages had the same timestamp the relative order between them was the
same as the one returned by the server. Due to this those messages were
sorted from newest to oldest between them, while the rest were sorted
from oldest to newest. The solution is to sort the models by their
reversed position in the set returned by the server.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The problem was caused by trying to disable the div using the "disabled"
property, which works only on real input fields; when using a content
editable div the way to disable it is by setting "contenteditable" to
"false".
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Otherwise your session times out while chatting and you can not
receive and post new messages after the 30 second timeout on your
session
Signed-off-by: Joas Schilling <coding@schilljs.com>
When two or more consecutive messages were sent by the same participant
with a difference of less than 120 seconds between each message those
messages are now shown grouped (the participant name is not shown for
the intermediate messages and each message is pushed closer to the
previous message).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The button is updated when the model changes, but the model was not
being synced when the user joined or left a call, so it only changed
when it was synced for any other reason.
Fixes#473
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When there is no password input field its value is undefined, so the
rendering never finished when calling "renderWhenInactive" due to the
strict equal comparison.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The tabIds list is already sorted by priority and insertion order, while
the regions order is undefined and has to be explicitly sorted.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Removing a tab from the right sidebar returns its content view, which
would be needed to move a view from the main area to the right sidebar
and back to the main area again (for example, the chat view).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
"selectTabHeader" now triggers a "select:tabHeader" event, which the
TabView handles by showing the appropriate content view. Thus, the click
events on tab headers can be directly handled with "selectTabHeader" and
"selectTab" no longer needs to explicitly show the content view.
Showing the appropriate content view when a tab header is selected
through "selectTabHeader" is a preparatory step to make possible to
remove tabs.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This fixes a UI issue with the standalone signaling where the interface
didn't switch back to the "Looking good" view when leaving a room.
Signed-off-by: Joachim Bauch <bauch@struktur.de>
The ChatView is a simplified version of CommentsTabView from the
Comments app, adapted to be used with ChatMessageCollection.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This prevents overloading both the browser and the server with
continuous and immediate requests when a fetch fails due to the server
returning an error (for example, if the user does not have access to a
room but its messages are tried to be received anyway).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
"stopReceivingMessages" must be called on ChatMessageCollections once
they are no longer needed to ensure that they do not keep polling the
server.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
"receiveMessages" sends a request to the server to get the messages; if
there is none to got the server keeps the connection open, causing
"receiveMessages" to wait until some message is available (or the
timeout ended, in which case the request would succeed but no message
would be returned). Once a response is got, "receiveMessages" sends a
new request to the server, and the process is repeated again and again.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
As chat messages can only be sent and received, but not updated or
deleted, a limited set of features are available only in the models:
sending a message is done by saving a ChatMessage, while receiving the
chat messages from a room is done by fetching a ChatMessageCollection.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Instead only get initial list when connecting and then only update when
notifications from the signaling server are received.
Signed-off-by: Joachim Bauch <bauch@struktur.de>
A standalone signaling server can be configured in the admin UI and is
notified through the BackendController on changes that should be sent to
connected clients.
See #339 for a description of the backend API.
Signed-off-by: Joachim Bauch <bauch@struktur.de>
If the attribute of the model to be shown in the label is empty the
label will now show the "labelPlaceholder" text set in the constructor
options, if any.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Only the code related to getting and setting the guest name in the UI
was modified to use the LocalStorageModel; direct calls to localStorage
to simply get the value in other areas were kept (and this change does
not affect their behaviour).
As "maxlength" in the guest name input field is set to "20" there is no
need to check the length of the new nick before setting it; if some
validation of the nick was needed before setting it it would have to be
done by using "validate" from Backbone on the model (and
EditableTextLabel would have to be extended too to provide feedback to
the user in that case).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The LocalStorageModel makes possible to use the local storage of the
browser as a Backbone model, for example, with a Marionette view.
It is introduced to be used in a later commit as a bridge between the
local storage of the browser and an EditableTextLabel for the name of
the guest.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When the CallInfoView is rendered the values set in the input fields but
not saved yet are lost. Therefore, instead of directly rendering the
view when the attributes of the model change it is first checked if an
edition is being performed and, it is, then the view is rendered once
the edition is finished.
"renderWhenInactive" assumes that the password is not being edited when
the field has no value. However, when the user set a password the field
was not automatically emptied, and thus the rendering was blocked
(unless the user manually emptied the field). To prevent this, now, once
the password is successfully set, the field is automatically emptied.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
An EditableTextLabel is a view that shows a single text attribute from a
Backbone model and, optionally, also makes possible to edit it.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The template uses the "displayName" attribute of the model to show the
name of the room, so that attribute should be used too in the functions
that change the room name.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The main page gives a user access to more than one room, while the
public page only gives a guest access to a single room; guests can not
even query the list of rooms in the backend, so the app sets a room
collection only for users, but not guests. Before, the room model only
supported being part of a room collection, so there was no room model to
be used by the UI for guests. Now, the room model was extended to
support both being part of a room collection and being a standalone
model, and now the signaling can synchronize a single room model too
instead of only a room collection, so the UI can rely on the room model
set as active to be up to date for both users and guests.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
When adding tabs to the right sidebar it is now possible to provide a
"priority" property to set the order of the tab header relative to the
other tab headers.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The ParticipantView was renamed to ParticipantListView and it is now a
subview of the new ParticipantView, which also contains the button to
add other participants to the room.
TODO: finish the actual movement of the button, as currently this commit
is just a skeleton with the changed views.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The ParticipantCollection provides the list of participants (including
guests) in a room. The Room model is synced through signaling and
provides some information about the registered users and the guests in a
room, so the ParticipantCollection can listen to changes in those
properties to automatically fetch its items again when needed.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Instead of being based on the "participantTabView" id the CSS rules used
by the ParticipantView were modified to be based on its class,
"participantWithList". This will make possible to change the parent
element of the ParticipantView and keep its style.
The rules for links were merged as those links that required a padding
due to being shown with an icon were also those shown inside the list
items.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The right sidebar will contain a call info view and a tab view to which
different sections can be added as needed.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
The right sidebar is an area that can be shown or hidden from the right
border of the document. It is a core element from Nextcloud, and
SidebarView is a Marionette wrapper around it. Therefore, it has to be
used along an "#app-content" element that takes into account the
"with-app-sidebar" CSS class.
However, this right sidebar extends the standard right sidebar with an
icon shown on the right border of the screen that makes possible for the
user to show it when hidden (as there is no other element in the UI
suitable for that purpose).
That icon is just a right-pointing triangle created with a CSS trick (a
zero-sized div with width borders, but all of them transparent except
for the left one). However, as the icon will be shown on different
coloured backgrounds it can not have just a single colour; it must
provide a border on its own too, which is achieved with another triangle
slightly larger underneath. The triangle border is 2px instead of just
1px used in other UI elements (like in the sidebar itself) to make it
more noticeable on a white background.
The triangle used for the icon is a large one, with a width of 24px and
a height of 48px. Using this trick has an added benefit, as its
clickable area is larger than the triangle itself (48x48px), which
improves its usability on touchable screens (and does not negatively
affect the experience on other devices).
Currently the SidebarView is empty. The content will be added in
following commits.
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
A TabView contains a set of tab headers and a content area. When a
header is selected its associated content view is shown in the content
area; otherwise its content is hidden (although the header is always
shown).
Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
This makes it easier to support different implementations in the future.
With this change also removed redundant message handling code from webrtc.js
that was also present in simplewebrtc.js.
Signed-off-by: Joachim Bauch <bauch@struktur.de>