Mercurial > libervia-templates
changeset 371:a5a80d761e3e
bulma (call): update template to integrate call features:
previously, call template was a minimum UI for testing implementation. This commit
introduce a usable UI with search interface, mute and full screen button, animations, and
other UI/UX improvments.
rel 423
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 09 Aug 2023 00:11:39 +0200 |
parents | 281d1c958d56 |
children | a603cf0fa5d1 |
files | sat_templates/templates/bulma/call/call.html sat_templates/templates/bulma/call/call_avatar.html sat_templates/templates/bulma/call/call_button.html sat_templates/templates/bulma/call/call_status.html sat_templates/templates/bulma/chat/message.html sat_templates/templates/bulma/static/call.css sat_templates/templates/bulma/static/styles.css |
diffstat | 7 files changed, 292 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/sat_templates/templates/bulma/call/call.html Mon Jul 10 15:43:49 2023 +0200 +++ b/sat_templates/templates/bulma/call/call.html Wed Aug 09 00:11:39 2023 +0200 @@ -4,32 +4,76 @@ {% endif %} {% block body %} -<section class="section"> + {{ icon_defs( + "resize-full", "resize-small", "volume-up", "videocam", "dot-3-vert", "wrench", "user-circle" + ) }} + <audio id="audio_player" class="is-hidden" src="{{media_path}}sounds/notifications/ring_1.mp3" preload="auto" loop></audio> + <section class="section is-full-below-menu" style="position: relative" > + <div id="containers_wrapper"> + + {# Search #} + <div id="search_container" class="is-overlay"> + <div id="search_header" class="columns is-1"> + <div class="column"> + <input class="input" type="search" id="search" placeholder="Enter contact's name or address"> + </div> - <div class="call_box"> - <video id="remote_video" autoplay playsinline></video> - <video id="local_video" autoplay playsinline muted></video> + <div class="column is-narrow buttons has-addons"> + <button class="button is-primary" id="call_btn"> + <i class="icon-videocam" aria-hidden="true"></i> + {% trans %}Video Call{% endtrans %} + </button> + <button class="button is-primary" id="toggle_call_mode_btn"> + <span class="icon is-small"> + <i class="icon-exchange" aria-hidden="true"></i> + </span> + </button> + </div> + </div> + + <div id="contacts" class="columns is-multiline is-mobile"> + </div> + </div> - <div class="field is-horizontal"> - <div class="field-label is-normal"> - <label class="label" for="jid">{% trans %}Callee JID{% endtrans %}</label> - </div> - <div class="field-body"> - <div class="field"> - <div class="control"> - <input class="input" type="text" id="callee_jid" value="louise@tazar3.int"> + {# Calls #} + <div class="is-hidden is-flex is-flex-direction-column" id="call_container"> + + <div class="columns is-1 is-centered is-vcentered m-0" id="call_header"> + <div class="column p-0"> + <div class="columns is-mobile is-1 is-vcentered m-0"> + <div class="column is-narrow px-0" id="call_avatar_wrapper"></div> + <div class="column" id="call_status_wrapper"></div> </div> </div> - <div class="field"> - <div class="control"> - <button class="button is-primary" id="call_btn">📞 {% trans %}Call{% endtrans %}</button> - <button class="button is-hidden" id="hangup_btn">{% trans %}Hang Up{% endtrans %}</button> - </div> + <div class="column is-narrow has-text-centered px-0" id="hangup_wrapper"> + <button class="button is-danger" id="hangup_btn">{% trans %}Hang Up{% endtrans %}</button> + </div> + </div> + + <div id="call_box" class="is-relative mt-3 is-flex-grow-1"> + <video id="remote_video" class="is-video-only" autoplay playsinline></video> + <div class="fullscreen-btn is-video-only"> + <button class="button is-light" id="full_screen_btn"> + {{ icon('resize-full', cls='image is-24x24 is-inline-block') }} + </button> + <button class="button is-light is-hidden" id="exit_full_screen_btn"> + {{ icon('resize-small', cls='image is-24x24 is-inline-block') }} + </button> + </div> + <video id="local_video" class="is-video-only" autoplay playsinline muted></video> + + <div class="controls is-flex is-justify-content-center is-align-items-center p-4"> + <button class="button is-success mx-2" id="mute_audio_btn"> + {{ icon('volume-up', cls='image is-24x24 is-inline-block') }} + </button> + <button class="button is-success mx-2 is-video-only" id="mute_video_btn"> + {{ icon('videocam', cls='image is-24x24 is-inline-block') }} + </button> </div> </div> </div> - +</div> </section> {% endblock body %}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sat_templates/templates/bulma/call/call_avatar.html Wed Aug 09 00:11:39 2023 +0200 @@ -0,0 +1,3 @@ +{% import 'components/avatar.html' as avatar with context %} + +{{ avatar.avatar(entity, "is-64x64") }}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sat_templates/templates/bulma/call/call_button.html Wed Aug 09 00:11:39 2023 +0200 @@ -0,0 +1,9 @@ +<button class="button {% if call_mode == 'video' %}is-success{% else %}is-dark{% endif %}" id="call_btn"> + {% if call_mode == 'video' %} + <i class="icon-videocam" aria-hidden="true"></i> + {% trans %}Video Call{% endtrans %} + {% else %} + <i class="icon-phone" aria-hidden="true"></i> + {% trans %}Audio Call{% endtrans %} + {% endif %} +</button>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sat_templates/templates/bulma/call/call_status.html Wed Aug 09 00:11:39 2023 +0200 @@ -0,0 +1,8 @@ +{% if status == none %} + <div class="call_status notification is-info column my-0"> + </div> +{% elif status == "dialing" %} + <div class="call_status notification is-info column my-0"> + <p>{% trans %}Calling {{name}}…{% endtrans %}</p> + </div> +{% endif %}
--- a/sat_templates/templates/bulma/chat/message.html Mon Jul 10 15:43:49 2023 +0200 +++ b/sat_templates/templates/bulma/chat/message.html Wed Aug 09 00:11:39 2023 +0200 @@ -63,7 +63,7 @@ {{ icon('doc', cls='icon') }} {%- endif %} <figcaption class="has-text-centered is-size-7"> - <a href="{{attachment.sources[0].url}}" target="_blank" class="has-text-grey">{{attachment.name}}</a> + <a href="{{attachment.sources[0].url if attachment.sources}}" target="_blank" class="has-text-grey">{{attachment.name}}</a> </figcaption> </figure> {%- endfor %}
--- a/sat_templates/templates/bulma/static/call.css Mon Jul 10 15:43:49 2023 +0200 +++ b/sat_templates/templates/bulma/static/call.css Wed Aug 09 00:11:39 2023 +0200 @@ -1,11 +1,14 @@ +#containers_wrapper { + position: relative; + height: 100%; + width: 100%; -.call_box { +} + +#call_container { + position: absolute; + height: 100%; width: 100%; - height: 500px; - position: relative; - overflow: hidden; - border: 1px solid #ddd; - margin-bottom: 15px; } #remote_video, #local_video { @@ -13,7 +16,8 @@ box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1); width: 100%; height: 100%; - object-fit: cover; + object-fit: contain; + background-color: #000; } #remote_video { @@ -22,11 +26,56 @@ left: 0; } +#hangup_btn { + padding-top: 2rem; + padding-bottom: 2rem; +} + +.fullscreen-btn { + position: absolute; + top: 10px; + right: 10px; + z-index: 2; +} + #local_video { position: absolute; - bottom: 10px; - right: 10px; + bottom: 0; + right: 0; width: 30%; height: 30%; } +.controls { + position: absolute; + bottom: 10px; + left: 0; + right: 0; + display: flex; + justify-content: center; + align-items: center; + z-index: 2; +} + +.muted::after { + content: "/"; + position: absolute; + font-size: 50px; + color: red; + top: 43%; + left: 52%; + transform: translate(-50%, -50%) rotate(45deg); +} + +.dropdown .dropdown-menu { + display: none; +} + +.dropdown.is-active .dropdown-menu { + display: block; +} + +.call_status { + padding-top: 1.3rem; + padding-bottom: 1.3rem; +}
--- a/sat_templates/templates/bulma/static/styles.css Mon Jul 10 15:43:49 2023 +0200 +++ b/sat_templates/templates/bulma/static/styles.css Wed Aug 09 00:11:39 2023 +0200 @@ -18,6 +18,12 @@ overflow: hidden; } +.is-full-below-menu { + /* full viewport minus top menu height */ + position:relative; + height: calc(100vh - 52px); +} + .has-whitespace-pre-wrap { white-space: pre-wrap; } @@ -613,3 +619,148 @@ transform: rotate(359deg); } } + + +/************** + * animations * + *************/ + +/* Fade In */ + +@keyframes fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +.fade-in { + animation: fade-in 0.5s ease-in forwards; +} + +@keyframes fade-in-x { + 0% { + opacity: 0; + transform: scaleX(0); + } + 100% { + opacity: 1; + transform: scaleX(1); + } +} + +.fade-in-x { + animation: fade-in-x 0.5s ease-in forwards; +} + +@keyframes fade-in-y { + 0% { + opacity: 0; + transform: scaleY(0); + } + 100% { + opacity: 1; + transform: scaleY(1); + } +} + +.fade-in-y { + animation: fade-in-y 0.5s ease-in forwards; +} + +@keyframes fade-in-xy { + 0% { + opacity: 0; + transform: scale(0); + } + 100% { + opacity: 1; + transform: scale(1); + } +} + +.fade-in-xy { + animation: fade-in-xy 0.5s ease-in forwards; +} + +/* Fade Out */ + +@keyframes fade-out { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} + +.fade-out { + animation: fade-out 0.5s ease-in forwards; +} + +@keyframes fade-out-x { + 0% { + opacity: 1; + transform: scaleX(1); + } + 100% { + opacity: 0; + transform: scaleX(0); + } +} + +.fade-out-x { + animation: fade-out-x 0.5s ease-in forwards; +} + +@keyframes fade-out-y { + 0% { + opacity: 1; + transform: scaleY(1); + } + 100% { + opacity: 0; + transform: scaleY(0); + } +} + +.fade-out-y { + animation: fade-out-y 0.5s ease-in forwards; +} + +@keyframes fade-out-xy { + 0% { + opacity: 1; + transform: scale(1); + } + 100% { + opacity: 0; + transform: scale(0); + } +} + +.fade-out-xy { + animation: fade-out-xy 0.5s ease-in forwards; +} + +/* Slide In */ +@keyframes slide-in { + 0% { + transform: translateY(100%); + opacity: 0; + } + 100% { + transform: translateY(0); + opacity: 1; + } +} + +.slide-in { + animation: slide-in 0.5s ease-in-out forwards; +} + +.animation-reverse { + animation-direction: reverse; +}