Change icons (notification, menus).

Simplify main menu.
Display call history by account.
Allow to remove reactions from chat.
Fix crash on conference creation.
This commit is contained in:
Julien Wadel 2023-09-08 11:44:13 +02:00
parent 820a34fd50
commit 369bc765e4
108 changed files with 3378 additions and 2679 deletions

View file

@ -9,9 +9,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Download path and emojis size settings
- Mac emoji font.
- Better SVG preview in thumbnails.
- Unstable forward message menu.
### Added
- Dedicated call history view.
- Chat reactions
- Update UI layouts.
## Removed
- Call events from chats.
- Missed call count in application side (done by SDK).
## 5.1.3 - Undefined

View file

@ -282,6 +282,9 @@ set(SOURCES
src/components/file/TemporaryFile.cpp
src/components/file/FileMediaModel.cpp
src/components/friend/FriendListListener.cpp
src/components/history/CallHistoryModel.cpp
src/components/history/CallHistoryListModel.cpp
src/components/history/CallHistoryProxyModel.cpp
src/components/history/HistoryModel.cpp
src/components/history/HistoryProxyModel.cpp
src/components/ldap/LdapModel.cpp
@ -429,6 +432,9 @@ set(HEADERS
src/components/file/TemporaryFile.hpp
src/components/file/FileMediaModel.hpp
src/components/friend/FriendListListener.hpp
src/components/history/CallHistoryModel.hpp
src/components/history/CallHistoryListModel.hpp
src/components/history/CallHistoryProxyModel.hpp
src/components/history/HistoryModel.hpp
src/components/history/HistoryProxyModel.hpp
src/components/ldap/LdapModel.hpp

View file

@ -4,7 +4,7 @@
height="80"
version="1.1"
id="svg4"
sodipodi:docname="call_history_custom2.svg"
sodipodi:docname="call_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
@ -21,11 +21,11 @@
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="6.7098284"
inkscape:cx="2.6081144"
inkscape:cy="59.763078"
inkscape:zoom="4.7445652"
inkscape:cx="-20.760596"
inkscape:cy="12.013746"
inkscape:window-width="1920"
inkscape:window-height="1131"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
@ -33,21 +33,10 @@
<path
d="m 20.032548,25.306346 c -2.922789,8.273156 1.173621,20.093116 7.803662,26.723927 l 0.139279,0.137194 c 6.627993,6.628763 18.450233,10.726431 26.718838,7.802159 l 6.271605,-8.22196 -8.541016,-8.539373 -7.815954,6.608287 -7.14209,-7.142763 -0.13723,-0.137195 -7.142092,-7.14276 6.607512,-7.818542 -8.53897,-8.53937 z"
stroke="#000000"
stroke-width="5.072"
stroke-width="3.072"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
id="path2"
style="stroke-width:5.2119685;stroke-miterlimit:4;stroke-dasharray:none;paint-order:normal" />
<path
d="m 63.999928,25.141826 a 9.230749,9.2313207 0 1 1 -18.461498,0 9.2307491,9.2313205 0 0 1 18.461498,0 z m -9.232801,-4.989014 v 5.060814 H 60.0625"
stroke="#000000"
stroke-width="3.03851"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"
stroke-linejoin="round"
id="path2-5"
style="stroke-width:3.17784;stroke-miterlimit:4;stroke-dasharray:none" />
id="path2" />
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -11,7 +11,7 @@
</defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="statut_avatar_busy_l">
<path d="M7.9995,16 C3.581,16 0,12.4185 0,8 C0,3.582 3.581,0 7.9995,0 C12.418,0 16,3.582 16,8 C16,12.4185 12.418,16 7.9995,16 Z" id="statut_avatar_busy_s" class="color-i-fill" fill="#FE5E00"></path>
<path d="M7.9995,16 C3.581,16 0,12.4185 0,8 C0,3.582 3.581,0 7.9995,0 C12.418,0 16,3.582 16,8 C16,12.4185 12.418,16 7.9995,16 Z" id="statut_avatar_busy_s" fill="#FF0000"></path>
<use id="statut_avatar_busy_s" stroke="#00FFFFFF" mask="url(#mask-2)" stroke-width="4" xlink:href="#path-1"></use>
</g>
</g>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -1,105 +1,112 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
id="Layer_1"
x="0px"
y="0px"
width="80"
height="80"
viewBox="0 0 80 80"
xml:space="preserve"
fill="none"
version="1.1"
id="svg27"
sodipodi:docname="filter_params_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs25" /><sodipodi:namedview
id="namedview23"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="13.640625"
inkscape:cx="33.319588"
inkscape:cy="40.687286"
inkscape:window-width="1920"
inkscape:window-height="1131"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<style
type="text/css"
id="style2">
.st0{fill:#000000;}
</style>
<g
id="g870"
transform="matrix(0,0.20833333,-0.22727273,0,69.090912,13.333333)"><rect
x="108"
y="64"
class="st0"
width="116"
height="16"
id="rect4" /><rect
x="32"
y="64"
class="st0"
width="24"
height="16"
id="rect6" /><path
class="st0"
d="m 84,56 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z"
id="path8" /><rect
x="132"
y="176"
class="st0"
width="92"
height="16"
id="rect10" /><rect
x="32"
y="176"
class="st0"
width="48"
height="16"
id="rect12" /><path
class="st0"
d="m 108,168 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z"
id="path14" /><rect
x="32"
y="120"
class="st0"
width="116"
height="16"
id="rect16" /><rect
x="200"
y="120"
class="st0"
width="24"
height="16"
id="rect18" /><path
class="st0"
d="m 172,112 c 8.8,0 16,7.2 16,16 0,8.8 -7.2,16 -16,16 -8.8,0 -16,-7.2 -16,-16 0,-8.8 7.2,-16 16,-16 m 0,-16 c -17.7,0 -32,14.3 -32,32 0,17.7 14.3,32 32,32 17.7,0 32,-14.3 32,-32 0,-17.7 -14.3,-32 -32,-32 z"
id="path20" /></g>
<path
style="fill:#000000;stroke-width:1.24628"
d="m 26.480571,39.100741 c -1.240541,-0.237768 -2.354137,-1.20884 -2.70286,-2.356933 -0.35178,-1.158159 -0.01556,-2.390762 0.876927,-3.214894 0.771356,-0.712275 1.553169,-1.015741 2.61684,-1.015741 1.471109,0 2.706656,0.729807 3.313172,1.95701 0.236125,0.477766 0.275153,0.632062 0.302022,1.194042 0.02517,0.526467 0.0012,0.734641 -0.130367,1.129851 -0.556222,1.671447 -2.400071,2.666163 -4.275734,2.306665 z"
id="path905" /><path
style="fill:#000000;stroke-width:1.24628"
d="m 39.130367,52.415919 c -1.751718,-0.380575 -3.023331,-2.107078 -2.740129,-3.720347 0.318831,-1.816233 2.097722,-3.045769 4.097474,-2.832096 1.959774,0.209401 3.422761,1.981513 3.115711,3.774055 -0.33496,1.955482 -2.388809,3.231208 -4.473056,2.778388 z"
id="path944" /><path
style="fill:#000000;stroke-width:1.24628"
d="m 51.897251,34.09053 c -1.291519,-0.28101 -2.396632,-1.29209 -2.713659,-2.482754 -0.438408,-1.646541 0.609221,-3.377901 2.385004,-3.941568 0.683573,-0.216979 1.70512,-0.214333 2.351222,0.0061 2.486916,0.848431 3.243723,3.649845 1.466208,5.42736 -0.882409,0.882409 -2.229224,1.264928 -3.488775,0.990873 z"
id="path983" /></svg>
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview29"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showgrid="false"
inkscape:zoom="4.9104638"
inkscape:cx="88.077221"
inkscape:cy="32.176187"
inkscape:window-width="1963"
inkscape:window-height="1209"
inkscape:window-x="26"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:current-layer="svg27" />
<g
filter="url(#filter0_b_26_3850)"
id="g14"
transform="matrix(2.7586207,0,0,2.7586207,11.034483,16.034483)">
<path
d="M 5,2 V 16.3347"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="round"
id="path2" />
<path
d="M 15,2 V 16.3347"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="round"
id="path4" />
<path
d="M 10,2 V 16.3347"
stroke="#000000"
stroke-width="1.5"
stroke-linecap="round"
id="path6" />
<circle
cx="5"
cy="5.72189"
r="1.25"
fill="#000000"
stroke="#000000"
stroke-width="1.5"
id="circle8" />
<circle
cx="15"
cy="5.72189"
r="1.25"
fill="#000000"
stroke="#000000"
stroke-width="1.5"
id="circle10" />
<circle
cx="10"
cy="12.7219"
r="1.25"
fill="#000000"
stroke="#000000"
stroke-width="1.5"
id="circle12" />
</g>
<defs
id="defs25">
<filter
id="filter0_b_26_3850"
x="-4"
y="-4"
width="29"
height="26"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB">
<feFlood
flood-opacity="0"
result="BackgroundImageFix"
id="feFlood16" />
<feGaussianBlur
in="BackgroundImageFix"
stdDeviation="2"
id="feGaussianBlur18" />
<feComposite
in2="SourceAlpha"
operator="in"
result="effect1_backgroundBlur_26_3850"
id="feComposite20" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="effect1_backgroundBlur_26_3850"
result="shape"
id="feBlend22" />
</filter>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -4,8 +4,8 @@
height="80"
version="1.1"
id="svg4"
sodipodi:docname="close_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="missed_incoming_call_custom.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@ -24,16 +24,18 @@
inkscape:zoom="4.1971154"
inkscape:cx="-29.66323"
inkscape:cy="23.34937"
inkscape:window-width="1920"
inkscape:window-height="1131"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
inkscape:window-width="1499"
inkscape:window-height="1111"
inkscape:window-x="26"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
d="M 27.255215,52.745704 51.112191,28.89804 52.772276,27.233933 27.255215,52.743448 Z m -0.01579,-25.511771 23.85472,23.849921 1.664598,1.659594 z"
d="M 23.08194,57.916804 55.684473,25.326996 57.953116,23.052856 23.08194,57.913721 Z m -0.02158,-34.863948 32.59945,32.592892 2.274811,2.267973 z"
stroke="#000000"
stroke-width="4.51043"
stroke-width="6.16388"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -4,8 +4,8 @@
height="80"
version="1.1"
id="svg4"
sodipodi:docname="close_custom.svg"
inkscape:version="1.1 (c68e22c387, 2021-05-23)"
sodipodi:docname="missed_outgoing_call_custom.svg"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
@ -22,18 +22,20 @@
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="4.1971154"
inkscape:cx="-29.66323"
inkscape:cx="-29.305842"
inkscape:cy="23.34937"
inkscape:window-width="1920"
inkscape:window-height="1131"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4" />
inkscape:current-layer="svg4"
inkscape:showpageshadow="2"
inkscape:deskcolor="#d1d1d1" />
<path
d="M 27.255215,52.745704 51.112191,28.89804 52.772276,27.233933 27.255215,52.743448 Z m -0.01579,-25.511771 23.85472,23.849921 1.664598,1.659594 z"
d="M 23.081774,57.918657 55.678996,25.326969 57.94727,23.052697 23.081774,57.915574 Z m -0.02158,-34.86596 32.594137,32.594771 2.274441,2.268106 z"
stroke="#000000"
stroke-width="4.51043"
stroke-width="6.16356"
fill="none"
fill-rule="evenodd"
stroke-linecap="round"

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -451,6 +451,34 @@
<translation>Šifrování médií</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -920,6 +948,11 @@ Adresa URL není nakonfigurována.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Schůzka byla smazána</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@ Adresa URL není nakonfigurována.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Vše</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Připojeno</translation>
</message>
<message>
<source>addContact</source>
<translation>PŘIDAT KONTAKT</translation>
@ -1049,21 +1079,24 @@ Adresa URL není nakonfigurována.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Chcete-li vytvořit chatovací místnost založenou na konferenci, musíte v nastavení účtu nastavit URI konference.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished">Místní kontakty</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTY</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>VŠE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>HOVORY</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ZPRÁVY</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Jste si jisti, že chcete tuto historii vymazat?</translation>
@ -1855,11 +1888,6 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Vyhledejte kontakt, začněte hovor nebo chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTY</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>automaticky</translation>
@ -1877,26 +1905,11 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Založit chatovací místnost</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Skrýt události</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Otevřít časovou osu</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Domů</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Schůzky</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,9 +1926,24 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Chcete stáhnout a použít konfiguraci z této adresy URL?</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation>Místní kontakty</translation>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -3944,26 +3972,6 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtr</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Vše</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Vlastní</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Místnosti s 1 a více účastníky</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3974,45 +3982,15 @@ Klikněte zde: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Skupiny chatu</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Povoleny mizející zprávy</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Hledat v seznamu</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Všechny úrovně zabezpečení</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standardní místnosti</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Jakékoli konverzace</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Mizející zap/vyp</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Bez mizejících</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Konference</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ Server url ikke konfigureret.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server url ikke konfigureret.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alle</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Forbundet</translation>
</message>
<message>
<source>addContact</source>
<translation>OPRET KONTAKT</translation>
@ -1042,21 +1072,24 @@ Server url ikke konfigureret.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>OPKALD</translation>
</message>
<message>
<source>displayMessages</source>
<translation>BESKEDER</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Er du sikker at du vil rydde op historikken?</translation>
@ -1844,11 +1877,6 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Søg en kontakt, start en samtale eller en chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTER</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>auto</translation>
@ -1866,26 +1894,11 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klik her: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation>Medienverschlüsselung</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ Server URL ist nicht konfiguriert.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Diese Besprechungen wurde gelöscht</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server URL ist nicht konfiguriert.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alle</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Verbunden</translation>
</message>
<message>
<source>addContact</source>
<translation>KONTAKT HINZUFÜGEN</translation>
@ -1042,21 +1072,24 @@ Server URL ist nicht konfiguriert.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Sie müssen eine Konferenz-URI in den Kontoeinstellungen festlegen um einen konferenzbasierten Chatraum zu erstellen.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTE</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLE</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ANRUFE</translation>
</message>
<message>
<source>displayMessages</source>
<translation>NACHRICHTEN</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Möchten Sie diese Historie wirklich löschen?</translation>
@ -1844,11 +1877,6 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Suche Kontakte, starte einen Anruf oder Chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTE</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>automatisch</translation>
@ -1866,26 +1894,11 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Starte einen Chatraum</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Verlauf verstecken</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Verlauf öffnen</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Startseite öffnen</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Besprechungen</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filter</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Alle</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Individuell</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Einfache Räume</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klicken Sie hier: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Chatgruppen</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kurzlebiges</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>In der Liste suchen</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation>Media encryption</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation>Call list</translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation>Incoming</translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation>Outgoing</translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation>Missed</translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation>Search in the list</translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ Server URL not configured.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>The meeting has been deleted</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation>Create Meeting</translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Server URL not configured.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>All</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Connected</translation>
</message>
<message>
<source>addContact</source>
<translation>ADD CONTACT</translation>
@ -1042,21 +1072,24 @@ Server URL not configured.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>You need to set the conference URI in your account settings to create a conference based chat room.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation>Local contacts</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>Contacts</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation>Online</translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALL</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CALLS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGES</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Are you sure you want to clear this history?</translation>
@ -1844,11 +1877,6 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Search contact, start a call or a chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTS</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>auto</translation>
@ -1866,26 +1894,11 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Start a chat room</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Hide Timeline</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Open Timeline</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Open Home</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Meetings</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,9 +1915,24 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Do you want to download and apply configuration from this URL?</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation>Local contacts</translation>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation>Open call history</translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation>Open chats</translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation>Open contacts</translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation>Open meetings</translation>
</message>
</context>
<context>
@ -3931,26 +3959,6 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filter</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>All</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Custom</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Simple rooms</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3961,45 +3969,15 @@ Click here: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Chat groups</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Ephemerals</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Search in the list</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>All security levels</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standard rooms</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Any conversations</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Ephemerals on/off</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Without ephemerals</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conferences</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation>Messages</translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ URL del servidor no configurada.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL del servidor no configurada.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Todo</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Conectado</translation>
</message>
<message>
<source>addContact</source>
<translation>AÑADIR CONTACTO</translation>
@ -1042,21 +1072,24 @@ URL del servidor no configurada.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Debe configurar el URL de la conferencia en la configuración de su cuenta para crear una conferencia basada en una sala de chat.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTACTOS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TODO</translation>
</message>
<message>
<source>displayCalls</source>
<translation>LLAMADAS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MENSAJES</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>¿Estás seguro de que quieres limpiar este historial?</translation>
@ -1844,11 +1877,6 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Buscar contacto, empezar una llamada o un chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTOS</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>automático</translation>
@ -1866,26 +1894,11 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Haga clic aquí: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation>Chiffrement du média</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ URL du serveur non configurée.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>La réunion a é supprimée</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL du serveur non configurée.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tous</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Connectés</translation>
</message>
<message>
<source>addContact</source>
<translation>AJOUTER UN CONTACT</translation>
@ -1042,21 +1072,24 @@ URL du serveur non configurée.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Vous devez définir l&apos;URI de la conférence dans les paramètres de votre compte pour créer une conférence.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished">Contacts locaux</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTACTS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TOUT</translation>
</message>
<message>
<source>displayCalls</source>
<translation>APPELS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGES</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Êtes-vous sûr de vouloir supprimer cet historique ?</translation>
@ -1844,11 +1877,6 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Chercher un contact, appeler ou envoyer un message</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTACTS</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>auto</translation>
@ -1866,26 +1894,11 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Commencer une conversation</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Masquer la chronologie</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Afficher la chronologie</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Ouvrir la page d&apos;accueil</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Réunions</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,9 +1915,24 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation>Voulez-vous télécharger et appliquer la configuration depuis cette adresse ?</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation>Contacts locaux</translation>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -3906,26 +3934,6 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtre</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Tous</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Personnalisé</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Standards</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,45 +3944,15 @@ Cliquez ici : &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Groupes standards</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Éphémères</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Rechercher dans la chronologie</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Tous les niveaux de sécurité</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standards</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Tous les types</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Éphémères on/off</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Sans éphémères</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conférences</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation>Média titkosítás</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -906,6 +934,11 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Összes</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Kapcsolódva</translation>
</message>
<message>
<source>addContact</source>
<translation>Névjegy hozzáadása</translation>
@ -1035,21 +1065,24 @@ A kiszolgáló URL-je nincs konfigurálva.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Konferenciaalapú csevegőszoba létrehozásához be kell állítania a konferencia URI-címét a fiókbeállításokban.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">Névjegyek</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>Összes</translation>
</message>
<message>
<source>displayCalls</source>
<translation>Hívások</translation>
</message>
<message>
<source>displayMessages</source>
<translation>Üzenetek</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Biztosan törölni kívánja ezt az előzményt?</translation>
@ -1833,11 +1866,6 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Névjegy keresése, hívás indítása vagy csevegés kezdése</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>Névjegyek</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>önműködő</translation>
@ -1855,26 +1883,11 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Csevegőszoba indítása</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Idővonal elrejtése</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Idővonal megnyitása</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Kezdőlap megnyitása</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3892,26 +3920,6 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Szűrő</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Összes</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Egyéni</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Egyszerű szobák</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,44 +3930,14 @@ Kattintson ide: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Csevegőcsoportok</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Elmúlók</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Keresés a listában</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Minden biztonsági szint</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Szabványos szobák</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Minden beszélgetés</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Elmúlók be/ki</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Elmúlók nélkül</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation>Criptaggio dei dati multimediali</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ URL del server non configurato.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL del server non configurato.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tutti</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Connesso</translation>
</message>
<message>
<source>addContact</source>
<translation>AGGIUNGI UN CONTATTO</translation>
@ -1042,21 +1072,24 @@ URL del server non configurato.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Per creare una chat di gruppo è necessario impostare la URI del gruppo nelle impostazioni del tuo account.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTATTI</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TUTTI</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CHIAMATE</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MESSAGGI</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Sei sicuro di voler cancellare questa cronologia?</translation>
@ -1844,11 +1877,6 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Cerca un contatto, avvia una chiamata o una chat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTATTI</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>auto</translation>
@ -1866,26 +1894,11 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Crea una chat di gruppo</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Nascondi Timeline</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Apri Timeline</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Apri Home</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Riunioni</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Clicca: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -906,6 +934,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation></translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation></translation>
</message>
<message>
<source>addContact</source>
<translation></translation>
@ -1035,21 +1065,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished">URIを設定する必要があります</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation></translation>
</message>
<message>
<source>displayCalls</source>
<translation></translation>
</message>
<message>
<source>displayMessages</source>
<translation></translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation></translation>
@ -1833,11 +1866,6 @@
<source>mainSearchBarPlaceholder</source>
<translation></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation></translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation></translation>
@ -1855,26 +1883,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,9 +1904,24 @@
<translation>URLから設定をダウンロードして適用しますか</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation></translation>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
@ -3892,26 +3920,6 @@
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,46 +3930,16 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"> ON/OFF</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation></translation>
</message>
</context>
<context>
<name>TimelineItem</name>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -920,6 +948,11 @@ Nesukonfigūruotas serverio url.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@ Nesukonfigūruotas serverio url.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Visi</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Prisijungę</translation>
</message>
<message>
<source>addContact</source>
<translation>PRIDĖTI KONTAKTĄ</translation>
@ -1049,21 +1079,24 @@ Nesukonfigūruotas serverio url.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTAI</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>VISKAS</translation>
</message>
<message>
<source>displayCalls</source>
<translation>SKAMBUČIAI</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ŽINUTĖS</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Ar tikrai norite išvalyti š istoriją?</translation>
@ -1855,11 +1888,6 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Ieškoti kontaktų, pradėti skambutį ar pokalbį</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTAI</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>automatinis</translation>
@ -1877,26 +1905,11 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3920,26 +3948,6 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,44 +3958,14 @@ Spustelėkite čia: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation>Encriptação da media</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ URL do servidor não configurado.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>A reunião foi excluída</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ URL do servidor não configurado.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Todos</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Conectado</translation>
</message>
<message>
<source>addContact</source>
<translation>ADICIONAR CONTATO</translation>
@ -1042,21 +1072,24 @@ URL do servidor não configurado.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Você precisa definir o URI da conferência nas configurações da sua conta para criar uma sala de bate-papo baseada em conferência.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">CONTATOS</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TODOS</translation>
</message>
<message>
<source>displayCalls</source>
<translation>CHAMADAS</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MENSAGENS</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Tem certeza de que deseja limpar esse histórico?</translation>
@ -1844,11 +1877,6 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Pesquisar contato, iniciar uma chamada ou um bate-papo</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>CONTATOS</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>Automático</translation>
@ -1866,26 +1894,11 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Iniciar uma sala de chat</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Ocultar linha do tempo</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Abrir linha do tempo</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Abrir a página inicial</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Reuniões</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<translation>Você deseja fazer o download e aplicar a configuração a partir desta URL?</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Filtro</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Todos</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Personalização</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Salas simples</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,45 +3944,15 @@ Clique aqui: &lt;a href=&quot;%1&quot;&gt;%1 &lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Grupo de chat</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Efêmeros</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Pesquisar na lista</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Todos níveis de segurança</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Salas padrão</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Todas conversas</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Efêmeros ligado/desligado</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Sem efêmeros</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Conferências</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation>Шифрование потока</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -920,6 +948,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation>Встреча была удалена</translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Все</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Подключенные</translation>
</message>
<message>
<source>addContact</source>
<translation>ДОБАВИТЬ КОНТАКТ</translation>
@ -1049,21 +1079,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Вам необходимо установить URI конференции в настройках вашего аккаунта, чтобы создать чат-комнату на основе конференции.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">КОНТАКТЫ</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ВСЕ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ЗВОНКИ</translation>
</message>
<message>
<source>displayMessages</source>
<translation>СООБЩЕНИЯ</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Вы уверены, что хотите очистить эту историю?</translation>
@ -1855,11 +1888,6 @@
<source>mainSearchBarPlaceholder</source>
<translation>Найти контакт, начать звонок или чат</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>КОНТАКТЫ</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>авто</translation>
@ -1877,26 +1905,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Начать чат-комнату</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Скрыть шкалу времени</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Открыть шкалу времени</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Открыть главную</translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation>Встречи</translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@
<translation>Вы хотите загрузить и применить конфигурацию с этого URL-адреса?</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3920,26 +3948,6 @@
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Фильтр</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Все</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Пользовательский</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Простые комнаты</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,45 +3958,15 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Чат-группы</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Недолговечные</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Поиск в списке</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Все уровни безопасности</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Стандартные комнаты</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Любые разговоры</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Недолговечные вкл/выкл</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Без недолговечных</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Конференции</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation>Mediekryptering</translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -913,6 +941,11 @@ Serverwebbadressen är inte konfigurerad.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1023,12 +1056,9 @@ Serverwebbadressen är inte konfigurerad.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Alla</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Ansluten</translation>
</message>
<message>
<source>addContact</source>
<translation>LÄGG TILL KONTAKT</translation>
@ -1042,21 +1072,24 @@ Serverwebbadressen är inte konfigurerad.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KONTAKTER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>ALLA</translation>
</message>
<message>
<source>displayCalls</source>
<translation>SAMTAL</translation>
</message>
<message>
<source>displayMessages</source>
<translation>MEDDELANDEN</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Är du säker att du vill rensa den här historiken?</translation>
@ -1844,11 +1877,6 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Sök kontakt, starta ett samtal eller en chatt</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KONTAKTER</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>automatiskt</translation>
@ -1866,26 +1894,11 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1902,8 +1915,23 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3906,26 +3934,6 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3936,44 +3944,14 @@ Klicka här: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -906,6 +934,11 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Tümü</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Bağlı</translation>
</message>
<message>
<source>addContact</source>
<translation>KİŞİ EKLE</translation>
@ -1035,21 +1065,24 @@ Sunucu url&apos;si yapılandırılmadı.</translation>
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation>Toplantı tabanlı konuşma odası oluşturmak için hesap ayarlarınızda toplantı URI&apos;si belirlemelisiniz.</translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">KİŞİLER</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>TÜMÜ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ÇAĞRILAR</translation>
</message>
<message>
<source>displayMessages</source>
<translation>İLETİLER</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Bu geçmişi temizlemek istediğinize emin misiniz?</translation>
@ -1833,11 +1866,6 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<source>mainSearchBarPlaceholder</source>
<translation>Kişi ara, çağrı veya sohbet başlat</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>KİŞİLER</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>kendiliğinden</translation>
@ -1855,26 +1883,11 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation>Konuşma odası başlat</translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>Zaman Çizelgesini Gizle</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>Zaman Çizelgesini </translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation>Evi </translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3892,26 +3920,6 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation>Süzgeç</translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation>Tümü</translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation>Özel</translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation>Basit odalar</translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,45 +3930,15 @@ Buraya tıklayın: &lt;a href=&quot;%1&quot;&gt;%1&lt;/a&gt;
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation>Konuşma kümeleri</translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kısa ömürlüler</translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation>Listede ara</translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation>Tüm güvenlik düzeyleri</translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation>Standart odalar</translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation>Herhangi konuşmalar</translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation>Kısa ömürlüler ık/kapalı</translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation>Kısa ömürlüler olmadan</translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<translation>Toplantılar</translation>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>

View file

@ -451,6 +451,34 @@
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -920,6 +948,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1030,12 +1063,9 @@
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation>Усі</translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation>Під&apos;єднані</translation>
</message>
<message>
<source>addContact</source>
<translation>ДОДАТИ КОНТАКТ</translation>
@ -1049,21 +1079,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished">КОНТАКТИ</translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation>УСІ</translation>
</message>
<message>
<source>displayCalls</source>
<translation>ВИКЛИКИ</translation>
</message>
<message>
<source>displayMessages</source>
<translation>ПОВІДОМЛЕННЯ</translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation>Ви впевнені, що волієте вичистити цю історію?</translation>
@ -1855,11 +1888,6 @@
<source>mainSearchBarPlaceholder</source>
<translation>Знайти контакт, почати дзвінок або чат</translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation>КОНТАКТИ</translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation>авто</translation>
@ -1877,26 +1905,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1913,8 +1926,23 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3920,26 +3948,6 @@
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3950,44 +3958,14 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -451,6 +451,34 @@
<translation></translation>
</message>
</context>
<context>
<name>CallTimeline</name>
<message>
<source>callListTitle</source>
<extracomment>&apos;Call list&apos; : Call histories title</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>incomingFilter</source>
<extracomment>&apos;Incoming&apos; : Filter label for incoming call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>outgoingFilter</source>
<extracomment>&apos;Outgoing&apos; : Filter label for outgoing call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>missedFilter</source>
<extracomment>&apos;Missed&apos; : Filter label for missed call</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>searchListPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in a list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>CallTransfer</name>
<message>
@ -906,6 +934,11 @@
<extracomment>&apos;The meeting has been deleted&apos; : Message text in a banner to warn the user that the meeting has been deleted.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>createMeeting</source>
<extracomment>&apos;Create Meeting&apos; : Button label to create a meeting</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ConfirmDialog</name>
@ -1016,12 +1049,9 @@
</message>
<message>
<source>selectAllContacts</source>
<extracomment>&apos;All&apos; : Filter label to display all items.</extracomment>
<translation></translation>
</message>
<message>
<source>selectConnectedContacts</source>
<translation></translation>
</message>
<message>
<source>addContact</source>
<translation></translation>
@ -1035,21 +1065,24 @@
<extracomment>&apos;You need to set the conference URI in your account settings to create a conference based chat room.&apos; : Tooltip to warn the user that a setting is missing in its configuration.</extracomment>
<translation> URI </translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>selectOnlineContacts</source>
<extracomment>&apos;Online&apos; : Filter label to display only online contacts.</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Conversation</name>
<message>
<source>displayCallsAndMessages</source>
<translation></translation>
</message>
<message>
<source>displayCalls</source>
<translation></translation>
</message>
<message>
<source>displayMessages</source>
<translation></translation>
</message>
<message>
<source>removeAllEntriesDescription</source>
<translation></translation>
@ -1833,11 +1866,6 @@
<source>mainSearchBarPlaceholder</source>
<translation></translation>
</message>
<message>
<source>contactsEntry</source>
<extracomment>&apos;Contacts&apos; : Contacts section label in main waindow.</extracomment>
<translation></translation>
</message>
<message>
<source>autoAnswerStatus</source>
<translation></translation>
@ -1855,26 +1883,11 @@
<extracomment>&apos;Start a chat room&apos; : Tooltip to illustrate a button</extracomment>
<translation></translation>
</message>
<message>
<source>hideTimeline</source>
<extracomment>&apos;Hide Timeline&apos; : Tooltip for a button that hide the timeline</extracomment>
<translation>线</translation>
</message>
<message>
<source>openTimeline</source>
<extracomment>&apos;Open Timeline&apos; : Tooltip for a button that open the timeline</extracomment>
<translation>线</translation>
</message>
<message>
<source>openHome</source>
<extracomment>&apos;Open Home&apos; : Tooltip for a button that open the home view</extracomment>
<translation></translation>
</message>
<message>
<source>mainWindowConferencesTitle</source>
<extracomment>&apos;Meetings&apos; : Meeting title for main window.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>newChatRoomUriMissing</source>
<extracomment>&apos;Conference URI is not set. You have to change it in your account settings in order to create new group chats.&apos; : Tooltip to warn the user to change a setting to activate an action.</extracomment>
@ -1891,8 +1904,23 @@
<translation type="unfinished"></translation>
</message>
<message>
<source>localContactsEntry</source>
<extracomment>&apos;Local contacts&apos; : Contacts section label in main window when we have to specify that they are local to the application.</extracomment>
<source>openCalls</source>
<extracomment>&apos;Open call history&apos; : Tooltip for a button that open the call history view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openChats</source>
<extracomment>&apos;Open chats&apos; : Tooltip for a button that open the conversations view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openContacts</source>
<extracomment>&apos;Open contacts&apos; : Tooltip for a button that open the contacts view</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>openMeetings</source>
<extracomment>&apos;Open meetings&apos; : Tooltip for a button that open the meetings list</extracomment>
<translation type="unfinished"></translation>
</message>
</context>
@ -3892,26 +3920,6 @@
</context>
<context>
<name>Timeline</name>
<message>
<source>timelineFilter</source>
<extracomment>A title for filtering mode.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAll</source>
<extracomment>&apos;All&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterCustom</source>
<extracomment>&apos;Custom&apos; The mode for timelines filtering.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSimpleRooms</source>
<extracomment>&apos;Simple rooms&apos; : Filter item. Selecting it will show all secure chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterSecureRooms</source>
<extracomment>&apos;Secure rooms&apos; : Filter item. Selecting it will show all secure rooms.</extracomment>
@ -3922,44 +3930,14 @@
<extracomment>&apos;Chat groups&apos; : Filter item. Selecting it will show all chat groups (with more than one participant).</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterEphemerals</source>
<extracomment>&apos;Ephemerals&apos; : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation></translation>
</message>
<message>
<source>timelineSearchPlaceholderText</source>
<extracomment>&apos;Search in the list&apos; : ths is a placeholder when searching something in the timeline list</extracomment>
<translation></translation>
</message>
<message>
<source>timelineFilterAllSecureLevelRooms</source>
<extracomment>&apos;All security levels&apos; : Filter item. Selecting it will not do any filter on security level.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterStandardRooms</source>
<extracomment>&apos;Standard rooms&apos; : Filter item. Selecting it will show all simple rooms.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyChatRooms</source>
<extracomment>&apos;Any conversations&apos; : Filter item. Selecting it will not do any filter on the type of conversations.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterAnyEphemerals</source>
<extracomment>&apos;Ephemerals on/off&apos; : Filter item. Selecting it will not do any filter on ephemerals activation.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterNoEphemerals</source>
<extracomment>&apos;No Ephemerals&apos; : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.</extracomment>
<translation type="unfinished"></translation>
</message>
<message>
<source>timelineFilterConferences</source>
<extracomment>&apos;Conferences&apos; : Filter item. Selecting it will show all conferences.</extracomment>
<source>chatsTitle</source>
<extracomment>&apos;Messages&apos; : Title for conversations</extracomment>
<translation type="unfinished"></translation>
</message>
</context>

View file

@ -432,6 +432,7 @@
<file>ui/modules/Linphone/Styles/Sticker/DecorationStickerStyle.qml</file>
<file>ui/modules/Linphone/Styles/Sticker/StickerStyle.qml</file>
<file>ui/modules/Linphone/Styles/TelKeypad/TelKeypadStyle.qml</file>
<file>ui/modules/Linphone/Styles/Timeline/CallTimelineStyle.qml</file>
<file>ui/modules/Linphone/Styles/Timeline/TimelineStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsListViewStyle.qml</file>
<file>ui/modules/Linphone/Styles/View/ParticipantsViewStyle.qml</file>
@ -439,6 +440,8 @@
<file>ui/modules/Linphone/TelKeypad/TelKeypadButton.qml</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.js</file>
<file>ui/modules/Linphone/TelKeypad/TelKeypad.qml</file>
<file>ui/modules/Linphone/Timeline/CallTimeline.qml</file>
<file>ui/modules/Linphone/Timeline/CallTimelineItem.qml</file>
<file>ui/modules/Linphone/Timeline/Timeline.js</file>
<file>ui/modules/Linphone/Timeline/Timeline.qml</file>
<file>ui/modules/Linphone/Timeline/TimelineItem.qml</file>
@ -477,12 +480,14 @@
<file>ui/views/App/Main/Assistant/UseAppSipAccountWithPhoneNumber.qml</file>
<file>ui/views/App/Main/Assistant/UseAppSipAccountWithUsername.qml</file>
<file>ui/views/App/Main/Assistant/UseOtherSipAccount.qml</file>
<file>ui/views/App/Main/Calls.qml</file>
<file>ui/views/App/Main/Conferences.qml</file>
<file>ui/views/App/Main/ContactEdit.js</file>
<file>ui/views/App/Main/ContactEdit.qml</file>
<file>ui/views/App/Main/Contacts.qml</file>
<file>ui/views/App/Main/Conversation.js</file>
<file>ui/views/App/Main/Conversation.qml</file>
<file>ui/views/App/Main/Conversations.qml</file>
<file>ui/views/App/Main/Dialogs/About.qml</file>
<file>ui/views/App/Main/Dialogs/AuthenticationRequest.js</file>
<file>ui/views/App/Main/Dialogs/AuthenticationRequest.qml</file>

View file

@ -51,6 +51,8 @@
#include "translator/DefaultTranslator.hpp"
#include "utils/Utils.hpp"
#include "utils/Constants.hpp"
#include "components/history/CallHistoryModel.hpp"
#include "components/history/CallHistoryProxyModel.hpp"
#include "components/other/desktop-tools/DesktopTools.hpp"
#include "components/other/date/DateModel.hpp"
@ -747,6 +749,7 @@ void App::registerTypes () {
registerType<TemporaryFile>("TemporaryFile");
registerType<TimeZoneProxyModel>("TimeZoneProxyModel");
registerType<CallHistoryProxyModel>("CallHistoryProxyModel");
registerType<ColorProxyModel>("ColorProxyModel");
registerType<ImageColorsProxyModel>("ImageColorsProxyModel");
registerType<ImageProxyModel>("ImageProxyModel");
@ -765,6 +768,7 @@ void App::registerTypes () {
registerUncreatableType<CallModel>("CallModel");
registerUncreatableType<CallHistoryModel>("CallHistoryModel");
registerUncreatableType<ChatCallModel>("ChatCallModel");
registerUncreatableType<ChatMessageModel>("ChatMessageModel");
registerUncreatableType<ChatNoticeModel>("ChatNoticeModel");

View file

@ -61,3 +61,6 @@ void ChatMessageListener::onEphemeralMessageTimerStarted(const std::shared_ptr<l
void ChatMessageListener::onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message){
emit ephemeralMessageDeleted(message);
}
void ChatMessageListener::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
emit reactionRemoved(message, address);
}

View file

@ -45,6 +45,7 @@ public:
virtual void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state) override;
virtual void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message) override;
virtual void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) override;
signals:
void fileTransferRecv(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, const std::shared_ptr<const linphone::Buffer> & buffer);
void fileTransferSendChunk(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<linphone::Content> & content, size_t offset, size_t size, const std::shared_ptr<linphone::Buffer> & buffer);
@ -55,6 +56,7 @@ signals:
void participantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void ephemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
void reactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
};
Q_DECLARE_METATYPE(ChatMessageListener*)

View file

@ -68,6 +68,7 @@ void ChatMessageModel::connectTo(ChatMessageListener * listener){
connect(listener, &ChatMessageListener::ephemeralMessageTimerStarted, this, &ChatMessageModel::onEphemeralMessageTimerStarted);
connect(listener, &ChatMessageListener::ephemeralMessageDeleted, this, &ChatMessageModel::onEphemeralMessageDeleted);
connect(listener, &ChatMessageListener::participantImdnStateChanged, this->getParticipantImdnStates().get(), &ParticipantImdnStateListModel::onParticipantImdnStateChanged);
connect(listener, &ChatMessageListener::reactionRemoved, this, &ChatMessageModel::onReactionRemoved);
}
// =============================================================================
@ -153,6 +154,12 @@ QString ChatMessageModel::getToSipAddress() const{
return mChatMessage ? Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getToAddress()->asStringUriOnly())) : "";
}
QString ChatMessageModel::getMyReaction() const {
if(!mChatMessage) return "";
auto myReaction = mChatMessage->getOwnReaction();
return myReaction ? Utils::coreStringToAppString(myReaction->getBody()) : "";
}
ContactModel * ChatMessageModel::getContactModel() const{
return mChatMessage ? CoreManager::getInstance()->getContactsListModel()->findContactModelFromSipAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(mChatMessage->getFromAddress()->asStringUriOnly()))).get() : nullptr;
}
@ -256,13 +263,16 @@ void ChatMessageModel::resendMessage (){
}
void ChatMessageModel::sendChatReaction(const QString& reaction){
auto chatReaction = mChatMessage->createReaction(Utils::appStringToCoreString(reaction));
if( mChatReactionListModel->exists(chatReaction)) {
chatReaction = mChatMessage->createReaction("");
return; // TODO : remove return when sending empty emoji will be supported.
auto myReaction = mChatMessage->getOwnReaction();
if( myReaction && Utils::coreStringToAppString(myReaction->getBody()) == reaction) {
auto chatReaction = mChatMessage->createReaction("");
chatReaction->send();
//emit reactionRemoved(mChatMessage, chatReaction->getFromAddress()); // Do not emit because we want to display what the server got
}else{
auto chatReaction = mChatMessage->createReaction(Utils::appStringToCoreString(reaction));
chatReaction->send();
//emit newMessageReaction(mChatMessage, chatReaction);// Do not emit because we want to display what the server got
}
chatReaction->send();
emit newMessageReaction(mChatMessage, chatReaction);
}
void ChatMessageModel::deleteEvent(){
@ -327,6 +337,8 @@ void ChatMessageModel::onMsgStateChanged (const std::shared_ptr<linphone::ChatMe
}
void ChatMessageModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){
if(reaction->getFromAddress()->weakEqual(message->getLocalAddress()))
emit myReactionChanged();
emit newMessageReaction(message, reaction);
}
@ -342,6 +354,12 @@ void ChatMessageModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone:
mContentListModel->removeDownloadedFiles();
emit remove(this);
}
void ChatMessageModel::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
if(address->weakEqual(message->getLocalAddress()))
emit myReactionChanged();
emit reactionRemoved(message, address);
}
//-------------------------------------------------------------------------------------------------------

View file

@ -74,6 +74,7 @@ public:
Q_PROPERTY(bool isForward READ isForward CONSTANT)
Q_PROPERTY(QString getForwardInfo READ getForwardInfo CONSTANT)
Q_PROPERTY(QString getForwardInfoDisplayName READ getForwardInfoDisplayName CONSTANT)
Q_PROPERTY(QString myReaction READ getMyReaction NOTIFY myReactionChanged)
std::shared_ptr<linphone::ChatMessage> getChatMessage();
@ -86,6 +87,7 @@ public:
QString getFromSipAddress() const;
QString getToDisplayName() const;
QString getToSipAddress() const;
QString getMyReaction() const;
ContactModel * getContactModel() const;
bool isEphemeral() const;
Q_INVOKABLE qint64 getEphemeralExpireTime() const;
@ -129,6 +131,7 @@ public:
void onParticipantImdnStateChanged(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ParticipantImdnState> & state);
void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> & message);
void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> & message);
void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
//----------------------------------------------------------------------------
bool mWasDownloaded;
@ -145,8 +148,10 @@ signals:
void isOutgoingChanged();
void fileContentChanged();
void remove(ChatMessageModel* model);
void myReactionChanged();
void newMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction);
void reactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
private:
void connectTo(ChatMessageListener * listener);

View file

@ -31,11 +31,15 @@ ChatReactionListModel::ChatReactionListModel (ChatMessageModel * message, QObjec
}
void ChatReactionListModel::setChatMessageModel(ChatMessageModel * message) {
if(mParent)
if(mParent) {
disconnect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
disconnect(message, &ChatMessageModel::reactionRemoved, this, &ChatReactionListModel::onReactionRemoved);
}
mParent = message;
if(mParent)
if(mParent) {
connect(message, &ChatMessageModel::newMessageReaction, this, &ChatReactionListModel::onNewMessageReaction);
connect(message, &ChatMessageModel::reactionRemoved, this, &ChatReactionListModel::onReactionRemoved);
}
if(message){
auto reactions = message->getChatMessage()->getReactions();
mReactions.clear();
@ -176,3 +180,12 @@ QStringList ChatReactionListModel::getBodies() const {
void ChatReactionListModel::onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction){
updateChatReaction(reaction);
}
void ChatReactionListModel::onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
mReactions.remove(Utils::coreStringToAppString(address->asStringUriOnly()));
mBodies.clear();
for(auto it : mReactions)
mBodies[it->getBody()].push_back(it);
updateList();
emit chatReactionCountChanged();
emit bodiesChanged();
}

View file

@ -65,6 +65,7 @@ public:
void updateList();
void onNewMessageReaction(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::ChatMessageReaction> & reaction);
void onReactionRemoved(const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
signals:
void chatReactionsChanged();
void chatReactionCountChanged();

View file

@ -23,6 +23,7 @@
#include <algorithm>
#include <QDateTime>
#include <QDebug>
#include <QDesktopServices>
#include <QElapsedTimer>
#include <QFileInfo>
@ -126,9 +127,6 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
// Get messages.
mList.clear();
mUnreadMessagesCount = mChatRoom->getUnreadMessagesCount();
mMissedCallsCount = 0;
QElapsedTimer timer;
timer.start();
CoreHandlers *coreHandlers = mCoreHandlers.get();
@ -145,7 +143,8 @@ ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoo
QObject::connect(coreManager->getContactsListModel(), &ContactsListModel::contactUpdated, this, &ChatRoomModel::avatarChanged);
connect(this, &ChatRoomModel::fullPeerAddressChanged, this, &ChatRoomModel::usernameChanged);
connect(this, &ChatRoomModel::stateChanged, this, &ChatRoomModel::updatingChanged);
connect(this, &ChatRoomModel::messageCountReset, this, &ChatRoomModel::unreadMessagesCountChanged);
connect(this, &ChatRoomModel::unreadMessagesCountChanged, coreManager, &CoreManager::eventCountChanged);
if(mChatRoom){
mParticipantListModel = QSharedPointer<ParticipantListModel>::create(this);
@ -408,6 +407,10 @@ LinphoneEnums::ChatRoomState ChatRoomModel::getState() const {
return mChatRoom ? LinphoneEnums::fromLinphone(mChatRoom->getState()) : LinphoneEnums::ChatRoomStateNone;
}
int ChatRoomModel::getUnreadMessagesCount() const{
return mChatRoom ? mChatRoom->getUnreadMessagesCount() : 0;
}
bool ChatRoomModel::isReadOnly() const{
return mChatRoom && mChatRoom->isReadOnly();
}
@ -531,10 +534,6 @@ QString ChatRoomModel::getParticipantAddress() const{
}
}
int ChatRoomModel::getAllUnreadCount(){
return mUnreadMessagesCount + mMissedCallsCount;
}
//------------------------------------------------------------------------------------------------
void ChatRoomModel::setSubject(QString& subject){
@ -564,31 +563,6 @@ void ChatRoomModel::updateLastUpdateTime(){
}
}
void ChatRoomModel::setUnreadMessagesCount(const int& count){
updateNewMessageNotice(count);
if(count != mUnreadMessagesCount){
mUnreadMessagesCount = count;
emit unreadMessagesCountChanged();
}
}
void ChatRoomModel::setMissedCallsCount(const int& count){
if(count != mMissedCallsCount){
mMissedCallsCount = count;
emit missedCallsCountChanged();
}
}
void ChatRoomModel::addMissedCallsCount(std::shared_ptr<linphone::Call> call){
insertCall(call->getCallLog());
auto timeline = CoreManager::getInstance()->getTimelineListModel()->getTimeline(mChatRoom, false);
if(!timeline || !timeline->mSelected){
setMissedCallsCount(mMissedCallsCount+1);
if(call->dataExists("call-model"))
CoreManager::getInstance()->getEventCountNotifier()->handleCallMissed(&call->getData<CallModel>("call-model"));
}
}
void ChatRoomModel::setEphemeralEnabled(bool enabled){
if(isEphemeralEnabled() != enabled){
mChatRoom->enableEphemeral(enabled);
@ -658,22 +632,6 @@ void ChatRoomModel::leaveChatRoom (){
void ChatRoomModel::updateParticipants(const QVariantList& participants){
/*
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
std::list <shared_ptr<linphone::Address> > chatRoomParticipants;
std::shared_ptr<const linphone::Address> localAddress;
for(auto p : participants){
ParticipantModel* participant = p.value<ParticipantModel*>();
auto address = Utils::interpretUrl(participant->getSipAddress());
if( address)
chatRoomParticipants.push_back( address );
}
if(mChatRoom->canHandleParticipants()) {
mChatRoom->addParticipants(newParticipants);
mChatRoom->removeParticipants(removeParticipants);
}
linphone::ChatRoom;*/
}
// -----------------------------------------------------------------------------
@ -751,12 +709,8 @@ void ChatRoomModel::resetMessageCount () {
if (mChatRoom->getUnreadMessagesCount() > 0){
mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls.
}
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
}else
setUnreadMessagesCount(0);
setMissedCallsCount(0);
}
emit messageCountReset();
CoreManager::getInstance()->updateUnreadMessageCount();
}
}
//-------------------------------------------------
@ -976,21 +930,7 @@ void ChatRoomModel::initEntries(){
// Get events
for(auto &eventLog : mChatRoom->getHistoryEvents(mFirstLastEntriesStep))
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
// Get calls.
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
bool noChat = !secureChatEnabled && !standardChatEnabled;
if(noChat || (isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure())) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
// callhistory is sorted from newest to oldest
int count = 0;
for (auto callLog = callHistory.begin() ; count < mFirstLastEntriesStep && callLog != callHistory.end() ; ++callLog, ++count ){
if(!(*callLog)->wasConference())
prepareEntries << EntrySorterHelper((*callLog)->getStartDate(), CallEntry, *callLog);
}
}
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mFirstLastEntriesStep, this);
qDebug() << "Internal Entries : Built";
if(entries.size() >0){
@ -1053,27 +993,7 @@ int ChatRoomModel::loadMoreEntries(){
if(!haveEntry)
prepareEntries << EntrySorterHelper(ChatMessageModel::initReceivedTimestamp(message, false).toTime_t() ,MessageEntry, message);
}
// Calls
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
bool noChat = !secureChatEnabled && !standardChatEnabled;
if( noChat || (isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|| standardChatEnabled && !isSecure())) ) {
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
int count = 0;
auto itCallHistory = callHistory.begin();
while(count < entriesCounts[1] && itCallHistory != callHistory.end()){
++itCallHistory;
++count;
}
count = 0;
while( count < mLastEntriesStep && itCallHistory != callHistory.end()){
prepareEntries << EntrySorterHelper((*itCallHistory)->getStartDate(), CallEntry, *itCallHistory);
++itCallHistory;
}
}
// Notices
for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){
auto itEntries = mList.begin();
@ -1114,58 +1034,12 @@ int ChatRoomModel::loadMoreEntries(){
//-------------------------------------------------
void ChatRoomModel::onCallEnded(std::shared_ptr<linphone::Call> call){
if( call->getCallLog()->getStatus() == linphone::Call::Status::Missed)
addMissedCallsCount(call);
else{
insertCall(call->getCallLog());
}
// When a call is end, a new log WILL be written in database. It may have information on display name.
QTimer::singleShot(100, this, &ChatRoomModel::fullPeerAddressChanged);
}
// -----------------------------------------------------------------------------
void ChatRoomModel::insertCall (const std::shared_ptr<linphone::CallLog> &callLog) {
if(mIsInitialized){
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true);
if(model){
int row = mList.count();
beginInsertRows(QModelIndex(), row, row);
mList << model;
endInsertRows();
auto lastIndex = index(mList.size()-1,0);
emit dataChanged(lastIndex,lastIndex );
if (callLog->getStatus() == linphone::Call::Status::Success) {
model = ChatCallModel::create(callLog, false);
if(model)
add(model);
}
updateLastUpdateTime();
}
}
}
void ChatRoomModel::insertCalls (const QList<std::shared_ptr<linphone::CallLog> > &calls) {
if(mIsInitialized){
QList<QSharedPointer<QObject> > entries;
for(auto callLog : calls) {
QSharedPointer<ChatCallModel> model = ChatCallModel::create(callLog, true);
if(model){
entries << model;
if (callLog->getStatus() == linphone::Call::Status::Success) {
model = ChatCallModel::create(callLog, false);
if(model){
entries << model;
}
}
}
}
if(entries.size() > 0){
prepend(entries);
}
}
}
QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message) {
QSharedPointer<ChatMessageModel> model;
if(mIsInitialized && !exists(message)){
@ -1173,7 +1047,7 @@ QSharedPointer<ChatMessageModel> ChatRoomModel::insertMessageAtEnd (const std::s
if(model){
qDebug() << "Adding at end" << model->getReceivedTimestamp().toString("hh:mm:ss.zzz") << model->getTimestamp().toString("hh:mm:ss.zzz") << QString(message->getUtf8Text().c_str()).left(5);
connect(model.get(), &ChatMessageModel::remove, this, &ChatRoomModel::removeEntry);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
emit unreadMessagesCountChanged();
add(model);
}
}
@ -1192,7 +1066,7 @@ void ChatRoomModel::insertMessages (const QList<std::shared_ptr<linphone::ChatMe
}
if(entries.size() > 0){
prepend(entries);
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
emit unreadMessagesCountChanged();
}
}
}
@ -1234,30 +1108,9 @@ QString ChatRoomModel::getChatRoomId(const std::shared_ptr<linphone::ChatRoom>&
return getChatRoomId(Utils::coreStringToAppString(localAddress->asStringUriOnly()), (chatRoom->getPeerAddress() ? Utils::coreStringToAppString(chatRoom->getPeerAddress()->asStringUriOnly()) : ""));
}
// -----------------------------------------------------------------------------
/*
void ChatRoomModel::removeUnreadMessagesNotice() {
}*/
// -----------------------------------------------------------------------------
void ChatRoomModel::handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state) {
/*
if (state == linphone::Call::State::End || state == linphone::Call::State::Error){
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
std::shared_ptr<linphone::ChatRoomParams> params = core->createDefaultChatRoomParams();
std::list<std::shared_ptr<linphone::Address>> participants;
auto chatRoom = core->searchChatRoom(params, mChatRoom->getLocalAddress()
, call->getRemoteAddress()
, participants);
if( mChatRoom == chatRoom){
insertCall(call->getCallLog());
setMissedCallsCount(mMissedCallsCount+1);
}
}
*/
}
void ChatRoomModel::handleCallCreated(const shared_ptr<linphone::Call> &call){
@ -1269,8 +1122,6 @@ void ChatRoomModel::handlePresenceStatusReceived(std::shared_ptr<linphone::Frien
bool canUpdatePresence = false;
auto contactAddresses = contact->getAddresses();
for( auto itContactAddress = contactAddresses.begin() ; !canUpdatePresence && itContactAddress != contactAddresses.end() ; ++itContactAddress){
//auto cleanContactAddress = (*itContactAddress)->clone();
//cleanContactAddress->clean();
canUpdatePresence = mChatRoom->getLocalAddress()->weakEqual(*itContactAddress);
if(!canUpdatePresence && !isGroupEnabled() && mChatRoom->getNbParticipants() == 1){
auto participants = getParticipants(false);
@ -1285,7 +1136,6 @@ void ChatRoomModel::handlePresenceStatusReceived(std::shared_ptr<linphone::Frien
}
}
if(canUpdatePresence) {
//emit presenceStatusChanged((int)contact->getPresenceModel()->getConsolidatedPresence());
emit presenceStatusChanged();
}
}
@ -1308,23 +1158,21 @@ void ChatRoomModel::onIsComposingReceived(const std::shared_ptr<linphone::ChatRo
void ChatRoomModel::onMessageReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message){
if(message) ChatMessageModel::initReceivedTimestamp(message, true);
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount());
emit unreadMessagesCountChanged();
updateLastUpdateTime();
}
void ChatRoomModel::onMessagesReceived(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::ChatMessage>> & messages){
for(auto message : messages)
if(message) ChatMessageModel::initReceivedTimestamp(message, true);
setUnreadMessagesCount(chatRoom->getUnreadMessagesCount());
emit unreadMessagesCountChanged();
updateLastUpdateTime();
}
void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){
if(eventLog){
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCallEnded ){
setMissedCallsCount(mMissedCallsCount+1);
}else if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated ){
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated ){
emit fullPeerAddressChanged();
}
updateLastUpdateTime();
@ -1332,17 +1180,12 @@ void ChatRoomModel::onNewEvent(const std::shared_ptr<linphone::ChatRoom> & chatR
}
void ChatRoomModel::onNewEvents(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::list<std::shared_ptr<linphone::EventLog>> & eventLogs){
int missCount = 0;
bool updatePeerAddress = false;
for(auto eventLog : eventLogs)
if(eventLog){
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCallEnded )
++missCount;
if( eventLog->getType() == linphone::EventLog::Type::ConferenceCreated )
updatePeerAddress = true;
}
if(missCount > 0)
setMissedCallsCount(mMissedCallsCount+missCount);
if(updatePeerAddress)
emit fullPeerAddressChanged();
updateLastUpdateTime();
@ -1470,7 +1313,7 @@ void ChatRoomModel::onConferenceJoined(const std::shared_ptr<linphone::ChatRoom>
if(e != events.end() )
insertNotice(*e);
}
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount()); // Update message count. In the case of joining conference, the conference id was not valid thus, the missing count was not about the chat room but a global one.
emit unreadMessagesCountChanged();// Update message count. In the case of joining conference, the conference id was not valid thus, the missing count was not about the chat room but a global one.
updateLastUpdateTime();
emit usernameChanged();
emit conferenceJoined(eventLog);

View file

@ -61,8 +61,7 @@ public:
Q_PROPERTY(QString subject READ getSubject WRITE setSubject NOTIFY subjectChanged)
Q_PROPERTY(QDateTime lastUpdateTime MEMBER mLastUpdateTime WRITE setLastUpdateTime NOTIFY lastUpdateTimeChanged)
Q_PROPERTY(int unreadMessagesCount MEMBER mUnreadMessagesCount WRITE setUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
Q_PROPERTY(int missedCallsCount MEMBER mMissedCallsCount WRITE setMissedCallsCount NOTIFY missedCallsCountChanged)
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
Q_PROPERTY(int securityLevel READ getSecurityLevel NOTIFY securityLevelChanged)
Q_PROPERTY(bool groupEnabled READ isGroupEnabled NOTIFY groupEnabledChanged)
@ -124,6 +123,7 @@ public:
int getPresenceStatus() const;
QDateTime getPresenceTimestamp() const;
LinphoneEnums::ChatRoomState getState() const;
int getUnreadMessagesCount() const;
bool isReadOnly() const;
bool isEphemeralEnabled() const;
long getEphemeralLifetime() const;
@ -149,7 +149,6 @@ public:
std::list<std::shared_ptr<linphone::Participant>> getParticipants(const bool& withMe = true) const;
std::shared_ptr<linphone::ChatRoom> getChatRoom();
QList<QString> getComposers();
int getAllUnreadCount(); // Return unread messages and missed call.
//---- Setters
void setSubject(QString& subject);
@ -157,9 +156,6 @@ public:
void updateLastUpdateTime();
void setEntriesLoading(const bool& loading);
void setUnreadMessagesCount(const int& count);
void setMissedCallsCount(const int& count);
void addMissedCallsCount(std::shared_ptr<linphone::Call> call);
void setEphemeralEnabled(bool enabled);
void setEphemeralLifetime(long lifetime);
void enableMarkAsRead(const bool& enable);
@ -196,8 +192,6 @@ public:
virtual void resetData() override;
QDateTime mLastUpdateTime;
int mUnreadMessagesCount = 0;
int mMissedCallsCount = 0;
bool mIsInitialized = false;
bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor
@ -206,9 +200,6 @@ public:
bool mMarkAsReadEnabled = true;
bool mEntriesLoading = false;
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
void insertCalls (const QList<std::shared_ptr<linphone::CallLog> > &calls);
QSharedPointer<ChatMessageModel> insertMessageAtEnd (const std::shared_ptr<linphone::ChatMessage> &message);
void insertMessages (const QList<std::shared_ptr<linphone::ChatMessage> > &messages);
void insertNotice (const std::shared_ptr<linphone::EventLog> &enventLog);
@ -280,7 +271,6 @@ signals:
void presenceStatusChanged();
void lastUpdateTimeChanged();
void unreadMessagesCountChanged();
void missedCallsCountChanged();
void securityLevelChanged(int securityLevel);
void groupEnabledChanged(bool groupEnabled);

View file

@ -53,7 +53,10 @@ using namespace std;
// -----------------------------------------------------------------------------
QSharedPointer<ConferenceInfoModel> ConferenceInfoModel::create(std::shared_ptr<linphone::ConferenceInfo> conferenceInfo){
return QSharedPointer<ConferenceInfoModel>::create(conferenceInfo);
if(conferenceInfo)
return QSharedPointer<ConferenceInfoModel>::create(conferenceInfo);
else
return nullptr;
}
// Callable from QML

View file

@ -79,10 +79,10 @@ bool ContactsListProxyModel::filterAcceptsRow (
mWeights[contact] = uint(round(computeContactWeight(contact)));
return mWeights[contact] > 0 && (
!mUseConnectedFilter ||
contact->getPresenceLevel() != Presence::PresenceLevel::White
);
return mWeights[contact] > 0
&& (!mUseConnectedFilter || contact->getPresenceLevel() != Presence::PresenceLevel::White)
&& (!mUseOnlineFilter || contact->getPresenceLevel() == Presence::PresenceLevel::Green)
;
}
bool ContactsListProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
@ -150,3 +150,10 @@ void ContactsListProxyModel::setConnectedFilter (bool useConnectedFilter) {
invalidate();
}
}
void ContactsListProxyModel::setOnlineFilter (bool useOnlineFilter) {
if (useOnlineFilter != mUseOnlineFilter) {
mUseOnlineFilter = useOnlineFilter;
invalidate();
}
}

View file

@ -31,11 +31,8 @@ class ContactsListModel;
class ContactsListProxyModel : public QSortFilterProxyModel {
Q_OBJECT;
Q_PROPERTY(
bool useConnectedFilter
READ isConnectedFilterUsed
WRITE setConnectedFilter
);
Q_PROPERTY(bool useConnectedFilter READ isConnectedFilterUsed WRITE setConnectedFilter);
Q_PROPERTY(bool useOnlineFilter READ isOnlineFilterUsed WRITE setOnlineFilter);
public:
ContactsListProxyModel (QObject *parent = Q_NULLPTR);
@ -53,11 +50,16 @@ private:
bool isConnectedFilterUsed () const {
return mUseConnectedFilter;
}
bool isOnlineFilterUsed () const {
return mUseOnlineFilter;
}
void setConnectedFilter (bool useConnectedFilter);
void setOnlineFilter (bool useOnlineFilter);
QString mFilter;
bool mUseConnectedFilter = false;
bool mUseOnlineFilter = false;
// It's just a cache to save values computed by `filterAcceptsRow`
// and reused by `lessThan`.

View file

@ -142,6 +142,8 @@ void CoreHandlers::onCallStateChanged (
const string &
) {
emit callStateChanged(call, state);
if (state == linphone::Call::State::End || state == linphone::Call::State::Error)
emit eventCountChanged();
SettingsModel *settingsModel = CoreManager::getInstance()->getSettingsModel();
if (

View file

@ -61,6 +61,8 @@ signals:
void setLastRemoteProvisioningState(const linphone::Config::ConfiguringState &state);
void conferenceInfoReceived(const std::shared_ptr<const linphone::ConferenceInfo> & conferenceInfo);
void foundQRCode(const std::string & result);
void eventCountChanged();
//-------------------- CORE HANDLER

View file

@ -93,6 +93,10 @@ void CoreListener::onNotifyPresenceReceived (const std::shared_ptr<linphone::Cor
void CoreListener::onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result){
emit qrcodeFound(core, result);
}
void CoreListener::onReactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) {
emit reactionRemoved(core, chatRoom, message, address);
}
void CoreListener::onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state){
emit transferStateChanged (core,call,state);
}

View file

@ -56,6 +56,7 @@ public:
virtual void onNotifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel) override;
virtual void onNotifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend) override;
virtual void onQrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result) override;
virtual void onReactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address) override;
virtual void onTransferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state) override;
virtual void onVersionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url) override;
virtual void onEcCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs) override;
@ -83,6 +84,7 @@ signals:
void notifyPresenceReceivedForUriOrTel (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend,const std::string &uriOrTel,const std::shared_ptr<const linphone::PresenceModel> &presenceModel);
void notifyPresenceReceived (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Friend> &linphoneFriend);
void qrcodeFound(const std::shared_ptr<linphone::Core> & core, const std::string & result);
void reactionRemoved(const std::shared_ptr<linphone::Core> & core, const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<linphone::ChatMessage> & message, const std::shared_ptr<const linphone::Address> & address);
void transferStateChanged (const std::shared_ptr<linphone::Core> &core,const std::shared_ptr<linphone::Call> &call,linphone::Call::State state);
void versionUpdateCheckResultReceived (const std::shared_ptr<linphone::Core> & core,linphone::VersionUpdateCheckResult result,const std::string &version,const std::string &url);
void ecCalibrationResult(const std::shared_ptr<linphone::Core> & core,linphone::EcCalibratorStatus status,int delayMs);

View file

@ -78,6 +78,7 @@ CoreManager::CoreManager (QObject *parent, const QString &configPath) :
QObject::connect(coreHandlers, &CoreHandlers::coreStopped, this, &CoreManager::stopIterate, Qt::QueuedConnection);
QObject::connect(coreHandlers, &CoreHandlers::logsUploadStateChanged, this, &CoreManager::handleLogsUploadStateChanged);
QObject::connect(coreHandlers, &CoreHandlers::callLogUpdated, this, &CoreManager::callLogsCountChanged);
QObject::connect(coreHandlers, &CoreHandlers::eventCountChanged, this, &CoreManager::eventCountChanged);
QTimer::singleShot(10, [this, configPath](){// Delay the creation in order to have the CoreManager instance set before
createLinphoneCore(configPath);
@ -97,6 +98,8 @@ void CoreManager::initCoreManager(){
mContactsListModel = new ContactsListModel(this);
mSipAddressesModel = new SipAddressesModel(this); // at first in order to prioritzed on handler signals.
mAccountSettingsModel = new AccountSettingsModel(this);
connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::missedCallsCountChanged);
connect(this, &CoreManager::eventCountChanged, mAccountSettingsModel, &AccountSettingsModel::unreadMessagesCountChanged);
mSettingsModel = new SettingsModel(this);
mEmojisSettingsModel = new EmojisSettingsModel(this);
mCallsListModel = new CallsListModel(this);
@ -106,8 +109,6 @@ void CoreManager::initCoreManager(){
mLdapListModel = new LdapListModel(this);
mEventCountNotifier = new EventCountNotifier(this);
mTimelineListModel = new TimelineListModel(this);
mEventCountNotifier->updateUnreadMessageCount();
QObject::connect(mEventCountNotifier, &EventCountNotifier::eventCountChanged,this, &CoreManager::eventCountChanged);
migrate();
mStarted = true;
@ -179,10 +180,16 @@ void CoreManager::forceRefreshRegisters () {
qInfo() << QStringLiteral("Refresh registers.");
mCore->refreshRegisters();
}
void CoreManager::updateUnreadMessageCount(){
mEventCountNotifier->updateUnreadMessageCount();
}
void CoreManager::resetMissedCallsCount(){
auto account = CoreManager::getInstance()->getCore()->getDefaultAccount();
if(account)
account->resetMissedCallsCount();
else
CoreManager::getInstance()->getCore()->resetMissedCallsCount();
emit eventCountChanged();
}
void CoreManager::stateChanged(Qt::ApplicationState pState){
if(mCbsTimer){
if(pState == Qt::ApplicationActive)
@ -403,12 +410,6 @@ int CoreManager::getEventCount () const {
int CoreManager::getCallLogsCount() const{
return mCore->getCallLogs().size();
}
int CoreManager::getMissedCallCount(const QString &peerAddress, const QString &localAddress)const{
return mEventCountNotifier ? mEventCountNotifier->getMissedCallCount(peerAddress, localAddress) : 0;
}
int CoreManager::getMissedCallCountFromLocal( const QString &localAddress)const{
return mEventCountNotifier ? mEventCountNotifier->getMissedCallCountFromLocal(localAddress) : 0;
}
std::list<std::shared_ptr<linphone::Account>> CoreManager::getAccountList()const{
std::list<std::shared_ptr<linphone::Account>> accounts;

View file

@ -155,15 +155,13 @@ public:
Q_INVOKABLE VcardModel *createDetachedVcardModel () const;
Q_INVOKABLE void forceRefreshRegisters ();
void updateUnreadMessageCount();
void resetMissedCallsCount();// Reset current default account or core if no default.
void stateChanged(Qt::ApplicationState pState);
Q_INVOKABLE void sendLogs () const;
Q_INVOKABLE void cleanLogs () const;
int getCallLogsCount() const;
int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
std::list<std::shared_ptr<linphone::Account>> getAccountList()const;

View file

@ -21,13 +21,8 @@
#include <QtDebug>
#include "components/call/CallModel.hpp"
#include "components/calls/CallsListModel.hpp"
#include "components/chat-room/ChatRoomModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/history/HistoryModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "utils/Utils.hpp"
#include "AbstractEventCountNotifier.hpp"
@ -37,116 +32,23 @@ using namespace std;
AbstractEventCountNotifier::AbstractEventCountNotifier (QObject *parent) : QObject(parent) {
CoreManager *coreManager = CoreManager::getInstance();
QObject::connect(
coreManager, &CoreManager::chatRoomModelCreated,
this, &AbstractEventCountNotifier::handleChatRoomModelCreated
);
QObject::connect(
coreManager, &CoreManager::historyModelCreated,
this, &AbstractEventCountNotifier::handleHistoryModelCreated
);
QObject::connect(
coreManager->getHandlers().get(), &CoreHandlers::messagesReceived,
this, &AbstractEventCountNotifier::updateUnreadMessageCount
);
QObject::connect(
coreManager->getSettingsModel(), &SettingsModel::standardChatEnabledChanged,
this, &AbstractEventCountNotifier::internalnotifyEventCount
);
QObject::connect(
coreManager->getSettingsModel(), &SettingsModel::secureChatEnabledChanged,
this, &AbstractEventCountNotifier::internalnotifyEventCount
);
QObject::connect(coreManager->getSettingsModel(), &SettingsModel::standardChatEnabledChanged, this, &AbstractEventCountNotifier::updateUnreadMessageCount);
QObject::connect(coreManager->getSettingsModel(), &SettingsModel::secureChatEnabledChanged, this, &AbstractEventCountNotifier::updateUnreadMessageCount);
/*
QObject::connect(
coreManager->getCallsListModel(), &CallsListModel::callMissed,
this, &AbstractEventCountNotifier::handleCallMissed
);*/
connect(coreManager, &CoreManager::eventCountChanged, this, &AbstractEventCountNotifier::eventCountChanged);
connect(this, &AbstractEventCountNotifier::eventCountChanged, this, &AbstractEventCountNotifier::internalNotifyEventCount);
}
// -----------------------------------------------------------------------------
void AbstractEventCountNotifier::updateUnreadMessageCount () {
int AbstractEventCountNotifier::getEventCount () const {
auto coreManager = CoreManager::getInstance();
if(!coreManager->getSettingsModel()->getStandardChatEnabled() && !coreManager->getSettingsModel()->getSecureChatEnabled())
mUnreadMessageCount = 0;
else
mUnreadMessageCount = CoreManager::getInstance()->getCore()->getUnreadChatMessageCountFromActiveLocals();
internalnotifyEventCount();
}
void AbstractEventCountNotifier::internalnotifyEventCount () {
int n = mUnreadMessageCount + getMissedCallCount();
qInfo() << QStringLiteral("Notify event count: %1.").arg(n);
n = n > 99 ? 99 : n;
notifyEventCount(CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled() || CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled()? n : 0);
emit eventCountChanged();
}
// Get missed call from a chat (useful for showing bubbles on Timelines)
int AbstractEventCountNotifier::getMissedCallCount(const QString &peerAddress, const QString &localAddress) const{
auto it = mMissedCalls.find({ Utils::cleanSipAddress(peerAddress), Utils::cleanSipAddress(localAddress) });
if (it != mMissedCalls.cend())
return *it;
else
return 0;
}
// Get missed call from a chat (useful for showing bubbles on Timelines)
int AbstractEventCountNotifier::getMissedCallCountFromLocal(const QString &localAddress) const{
QString cleanAddress = Utils::cleanSipAddress(localAddress);
int count = 0;
for(auto it = mMissedCalls.cbegin() ; it != mMissedCalls.cend() ; ++it){
if(it.key().second == cleanAddress)
count += *it;
}
int count = coreManager->getCore()->getMissedCallsCount();
if( coreManager->getSettingsModel()->getStandardChatEnabled() || coreManager->getSettingsModel()->getSecureChatEnabled())
count += coreManager->getCore()->getUnreadChatMessageCount();
return count;
}
// -----------------------------------------------------------------------------
void AbstractEventCountNotifier::handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel) {
ChatRoomModel *chatRoomModelPtr = chatRoomModel.get();
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::messageCountReset,
this, &AbstractEventCountNotifier::updateUnreadMessageCount
);
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::focused,
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
);
QObject::connect(
chatRoomModelPtr, &ChatRoomModel::messageCountReset,
this, [this, chatRoomModelPtr]() { handleResetMissedCalls(chatRoomModelPtr); }
);
}
void AbstractEventCountNotifier::handleHistoryModelCreated (HistoryModel *historyModel) {
QObject::connect(historyModel, &HistoryModel::callCountReset
, this, &AbstractEventCountNotifier::handleResetAllMissedCalls);
}
void AbstractEventCountNotifier::handleResetAllMissedCalls () {
mMissedCalls.clear();
internalnotifyEventCount();
}
void AbstractEventCountNotifier::handleResetMissedCalls (ChatRoomModel *chatRoomModel) {
auto it = mMissedCalls.find({ Utils::cleanSipAddress(chatRoomModel->getPeerAddress()), Utils::cleanSipAddress(chatRoomModel->getLocalAddress()) });
if (it != mMissedCalls.cend()) {
mMissedCalls.erase(it);
internalnotifyEventCount();
}
}
void AbstractEventCountNotifier::handleCallMissed (CallModel *callModel) {
++mMissedCalls[{ Utils::cleanSipAddress(callModel->getPeerAddress()), Utils::cleanSipAddress(callModel->getLocalAddress()) }];
internalnotifyEventCount();
}
void AbstractEventCountNotifier::handleCallMissed (const QString& localAddress, const QString& peerAddress) {
++mMissedCalls[{ peerAddress, localAddress }];
internalnotifyEventCount();
}
void AbstractEventCountNotifier::internalNotifyEventCount () {
int n = getEventCount();
qInfo() << QStringLiteral("Notify event count: %1.").arg(n);
n = n > 99 ? 99 : n;
notifyEventCount(n);
}

View file

@ -43,41 +43,18 @@ class AbstractEventCountNotifier : public QObject {
public:
AbstractEventCountNotifier (QObject *parent = Q_NULLPTR);
void updateUnreadMessageCount ();
int getUnreadMessageCount () const { return mUnreadMessageCount; }
int getMissedCallCount () const {
int t = 0;
for (int n : mMissedCalls) t += n;
return t;
}
int getEventCount () const { return mUnreadMessageCount + getMissedCallCount(); }
int getMissedCallCount(const QString &peerAddress, const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
int getMissedCallCountFromLocal(const QString &localAddress) const;// Get missed call count from a chat (useful for showing bubbles on Timelines)
int getUnreadMessageCount () const;
int getMissedCallCount () const;
int getEventCount () const;
signals:
void eventCountChanged ();
public slots:
void handleCallMissed (const QString& localAddress, const QString& peerAddress);
void handleResetAllMissedCalls ();
void handleResetMissedCalls (ChatRoomModel *chatRoomModel);
void handleCallMissed (CallModel *callModel);
protected:
virtual void notifyEventCount (int n) = 0;
private:
using ConferenceId = QPair<QString, QString>;
void internalnotifyEventCount ();
void handleChatRoomModelCreated (const QSharedPointer<ChatRoomModel> &chatRoomModel);
void handleHistoryModelCreated (HistoryModel *historyModel);
QHash<ConferenceId, int> mMissedCalls;
int mUnreadMessageCount = 0;
void internalNotifyEventCount ();
};
#endif // ABSTRACT_EVENT_COUNT_NOTIFIER_H_

View file

@ -60,11 +60,6 @@ EventCountNotifier::EventCountNotifier (QObject *parent) : AbstractEventCountNot
mBlinkTimer = new QTimer(this);
mBlinkTimer->setInterval(IconCounterBlinkInterval);
QObject::connect(mBlinkTimer, &QTimer::timeout, this, &EventCountNotifier::update);
Utils::connectOnce(
App::getInstance(), &App::focusWindowChanged,
this, &EventCountNotifier::updateUnreadMessageCount
);
}
EventCountNotifier::~EventCountNotifier () {

View file

@ -0,0 +1,123 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryListModel.hpp"
#include "CallHistoryModel.hpp"
#include "components/core/CoreManager.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp"
// =============================================================================
CallHistoryListModel::CallHistoryListModel (QObject *parent) : ProxyListModel(parent) {
reload();
connect(CoreManager::getInstance()->getHandlers().get(), &CoreHandlers::callLogUpdated, this, &CallHistoryListModel::onCallLogUpdated);
}
QString reorder(const QString& address){
QStringList splitted = address.split(";");
QString newAddress = splitted[0];
splitted.removeFirst();
splitted.sort();
return newAddress + splitted.join(";");
}
void CallHistoryListModel::reload() {
beginResetModel();
mList.clear();
endResetModel();
auto account = CoreManager::getInstance()->getCore()->getDefaultAccount();
auto callLogs = account ? account->getCallLogs() : CoreManager::getInstance()->getCore()->getCallLogs();
add(callLogs);
CoreManager::getInstance()->resetMissedCallsCount();
if(mList.size() > 0)
QTimer::singleShot(1, [&](){
mList.at(0).objectCast<CallHistoryModel>()->selectOnly();
});
}
CallHistoryListModel::~CallHistoryListModel(){
}
void CallHistoryListModel::add(const std::list<std::shared_ptr<linphone::CallLog>>& callLogs){
QList<QSharedPointer<CallHistoryModel>> toAdd;
for(auto callLog : callLogs) {
if(!callLog->getLocalAddress()->weakEqual(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress()))
continue;
QString confUri;
auto remoteAddress = callLog->getRemoteAddress()->clone();
remoteAddress->clean();
QString address = reorder(Utils::coreStringToAppString(remoteAddress->asStringUriOnly()));
if( callLog->getConferenceInfo()) {
confUri = reorder(Utils::coreStringToAppString(callLog->getConferenceInfo()->getUri()->asStringUriOnly()));
}
QString keyName = address + "/"+confUri;
if(!mCalls.contains(keyName)) {
auto call = QSharedPointer<CallHistoryModel>::create(callLog);
mCalls[keyName] = call;
connect(call.get(), &CallHistoryModel::selectOnlyRequested, this, &CallHistoryListModel::onSelectOnlyRequested);
connect(call.get(), &CallHistoryModel::selectedChanged, this, &CallHistoryListModel::onSelectedChanged);
connect(call.get(), &CallHistoryModel::hasBeenRemoved, this, &CallHistoryListModel::onHasBeenRemoved);
connect(call.get(), &CallHistoryModel::lastCallDateChanged, this, &CallHistoryListModel::lastCallDateChanged);
toAdd << call;
}else{
mCalls[keyName]->update(callLog);
}
}
ProxyListModel::add(toAdd);
}
void CallHistoryListModel::onCallLogUpdated(const std::shared_ptr<linphone::CallLog> &call){
add(std::list<std::shared_ptr<linphone::CallLog>>{call});
}
void CallHistoryListModel::onSelectOnlyRequested() {
for(auto model : mList){
auto callModel = model.objectCast<CallHistoryModel>();
if(callModel != sender())
callModel->setSelected(false);
}
}
void CallHistoryListModel::onSelectedChanged(bool selected, CallHistoryModel * model) {
if(selected) {
emit selectedChanged(model);
CoreManager::getInstance()->resetMissedCallsCount();
}
}
void CallHistoryListModel::onHasBeenRemoved(){
QString confUri;
auto model = qobject_cast<CallHistoryModel*>(sender());
QString address = reorder(model->getRemoteAddress());
if( model->wasConference()) {
confUri = reorder(Utils::coreStringToAppString(model->getConferenceInfoModel()->getConferenceInfo()->getUri()->asStringUriOnly()));
}
remove(sender());
QString keyName = address + "/"+confUri;
mCalls.remove(keyName);
if(model->mSelected) {
if(mList.size() > 0){
mList.at(0).objectCast<CallHistoryModel>()->selectOnly();
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_LIST_MODEL_H_
#define CALL_HISTORY_LIST_MODEL_H_
#include <QSharedPointer>
#include <linphone++/linphone.hh>
#include "app/proxyModel/ProxyListModel.hpp"
class CallHistoryModel;
// =============================================================================
class CallHistoryListModel : public ProxyListModel {
Q_OBJECT
public:
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
CallHistoryListModel (QObject *parent = Q_NULLPTR);
virtual ~CallHistoryListModel();
void reload();
void add(const std::list<std::shared_ptr<linphone::CallLog>>& callLog);
void onCallLogUpdated(const std::shared_ptr<linphone::CallLog> &call);
void onSelectedChanged(bool selected, CallHistoryModel * model);
void onSelectOnlyRequested();
void onHasBeenRemoved();
signals:
void countChanged();
void selectedChanged(CallHistoryModel * model);
void lastCallDateChanged();
private:
QHash<QString, QSharedPointer<CallHistoryModel>> mCalls;
};
#endif

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryModel.hpp"
#include "utils/Utils.hpp"
#include <QDebug>
CallHistoryModel::CallHistoryModel(QObject *parent) : QObject(parent){
}
CallHistoryModel::CallHistoryModel(const std::shared_ptr<linphone::CallLog> callLog, QObject *parent) : QObject(parent){
mRemoteAddress = callLog->getRemoteAddress()->clone();
mRemoteAddress->clean();
mLastCallStatus = LinphoneEnums::fromLinphone(callLog->getStatus());
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
mLastCallDate = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
mLastCallIsStart = false;
}else {
mLastCallDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
mLastCallIsStart = true;
}
mLastCallIsOutgoing = callLog->getDir() == linphone::Call::Dir::Outgoing;
mConferenceInfoModel = ConferenceInfoModel::create(callLog->getConferenceInfo());
if(!mConferenceInfoModel && callLog->wasConference())
qWarning() << "Was conf without info : " << Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
QString CallHistoryModel::getRemoteAddress() const{
return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
QString CallHistoryModel::getSipAddress() const{
if( mConferenceInfoModel )
return Utils::coreStringToAppString(mConferenceInfoModel->getConferenceInfo()->getUri()->asStringUriOnly());
else
return Utils::coreStringToAppString(mRemoteAddress->asStringUriOnly());
}
ConferenceInfoModel * CallHistoryModel::getConferenceInfoModel() const {
return mConferenceInfoModel.get();
}
bool CallHistoryModel::wasConference() const {
return mConferenceInfoModel;
}
QString CallHistoryModel::getTitle() const {
if(mConferenceInfoModel)
return mConferenceInfoModel->getSubject();
else
return "";
}
void CallHistoryModel::update(const std::shared_ptr<linphone::CallLog> callLog){
QDateTime callDate;
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
callDate = QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000);
}else {
callDate = QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
}
if(callDate >= mLastCallDate){
setLastCallStatus(LinphoneEnums::fromLinphone(callLog->getStatus()));
if(mShowEnd && mLastCallStatus == LinphoneEnums::CallStatusSuccess){
setLastCallDate(QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000));
setLastCallIsStart(false);
}else {
setLastCallDate(QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000));
setLastCallIsStart(true);
}
mConferenceInfoModel = ConferenceInfoModel::create(callLog->getConferenceInfo());
emit conferenceInfoModelChanged();
}
}
void CallHistoryModel::setLastCallStatus(LinphoneEnums::CallStatus status) {
if(mLastCallStatus != status){
mLastCallStatus = status;
emit lastCallStatusChanged();
}
}
void CallHistoryModel::setLastCallDate(const QDateTime& date) {
if( mLastCallDate != date) {
mLastCallDate = date;
emit lastCallDateChanged();
}
}
void CallHistoryModel::setLastCallIsStart(const bool& start) {
if( mLastCallIsStart != start) {
mLastCallIsStart = start;
emit lastCallIsStartChanged();
}
}
void CallHistoryModel::setLastCallIsOutgoing(const bool& outgoing){
if( mLastCallIsOutgoing != outgoing) {
mLastCallIsOutgoing = outgoing;
emit lastCallIsOutgoingChanged();
}
}
void CallHistoryModel::setSelected(const bool& selected){
if(selected != mSelected || selected){
mSelected = selected;
if(mSelected){
qInfo() << "Call room selected : Address :" << getRemoteAddress();
}else{
qInfo() << "Unselect call room "<< getRemoteAddress();
}
emit selectedChanged(mSelected, this);
}
}
void CallHistoryModel::selectOnly(){
setSelected(true);
emit selectOnlyRequested();
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_MODEL_H_
#define CALL_HISTORY_MODEL_H_
#include <QObject>
#include <QDateTime>
#include <linphone++/linphone.hh>
#include "components/conferenceInfo/ConferenceInfoModel.hpp"
#include "utils/LinphoneEnums.hpp"
class CallHistoryModel : public QObject {
Q_OBJECT
public:
Q_PROPERTY(QString remoteAddress READ getRemoteAddress CONSTANT) // strip from gruu/conf-id
Q_PROPERTY(QString sipAddress READ getSipAddress NOTIFY conferenceInfoModelChanged) // Use to call
Q_PROPERTY(bool selected MEMBER mSelected WRITE setSelected NOTIFY selectedChanged)
Q_PROPERTY(LinphoneEnums::CallStatus lastCallStatus MEMBER mLastCallStatus WRITE setLastCallStatus NOTIFY lastCallStatusChanged)
Q_PROPERTY(QDateTime lastCallDate MEMBER mLastCallDate WRITE setLastCallDate NOTIFY lastCallDateChanged)
Q_PROPERTY(bool lastCallIsStart MEMBER mLastCallIsStart WRITE setLastCallIsStart NOTIFY lastCallIsStartChanged)
Q_PROPERTY(bool lastCallIsOutgoing MEMBER mLastCallIsOutgoing WRITE setLastCallIsOutgoing NOTIFY lastCallIsOutgoingChanged)
Q_PROPERTY(ConferenceInfoModel * conferenceInfoModel READ getConferenceInfoModel NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(bool wasConference READ wasConference NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(QString title READ getTitle NOTIFY conferenceInfoModelChanged)
CallHistoryModel(QObject *parent = nullptr);
CallHistoryModel(const std::shared_ptr<linphone::CallLog> callLogs, QObject *parent = nullptr);
QString getRemoteAddress() const;
QString getSipAddress() const;
ConferenceInfoModel * getConferenceInfoModel() const;
bool wasConference() const;
QString getTitle() const;
void update(const std::shared_ptr<linphone::CallLog> callLog);
void setLastCallStatus(LinphoneEnums::CallStatus status);
void setLastCallDate(const QDateTime& date);
void setLastCallIsStart(const bool& start);
void setLastCallIsOutgoing(const bool& outgoing);
void setSelected(const bool& selected);
Q_INVOKABLE void selectOnly(); // Select this item and remove others in parent lists
QDateTime mLastCallDate;
bool mSelected = false;
bool mLastCallIsOutgoing;
LinphoneEnums::CallStatus mLastCallStatus;
signals:
void selectOnlyRequested();
void selectedChanged(bool selected, CallHistoryModel * model);
void lastCallStatusChanged();
void lastCallDateChanged();
void lastCallIsStartChanged();
void lastCallIsOutgoingChanged();
void conferenceInfoModelChanged();
void hasBeenRemoved();
private:
std::shared_ptr<linphone::Address> mRemoteAddress;
bool mLastCallIsStart;
QSharedPointer<ConferenceInfoModel> mConferenceInfoModel;
bool mShowEnd = false; // Display ended call (start + duration)
};
#endif

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CallHistoryProxyModel.hpp"
#include "CallHistoryListModel.hpp"
#include "CallHistoryModel.hpp"
#include "app/App.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp"
#include <QDebug>
#include <QQuickWindow>
// =============================================================================
// -----------------------------------------------------------------------------
CallHistoryProxyModel::CallHistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
auto model = new CallHistoryListModel();
setSourceModel(model);
sort(0);
connect(CoreManager::getInstance()->getAccountSettingsModel(), &AccountSettingsModel::defaultAccountChanged, model, &CallHistoryListModel::reload);
connect(model, &CallHistoryListModel::lastCallDateChanged, this, &CallHistoryProxyModel::invalidate);
App *app = App::getInstance();
connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
handleIsActiveChanged(App::getInstance()->getMainWindow());
});
}
// -----------------------------------------------------------------------------
void CallHistoryProxyModel::setFilterFlags(int filterFlags){
if( mFilterFlags != filterFlags){
mFilterFlags = filterFlags;
invalidate();
emit filterFlagsChanged();
}
}
void CallHistoryProxyModel::setFilterText(const QString& text){
if( mFilterText != text){
mFilterText = text;
invalidate();
emit filterTextChanged();
}
}
// -----------------------------------------------------------------------------
bool CallHistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const {
if(!sourceModel())
return false;
bool show = true;
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
auto timeline = sourceModel()->data(index).value<CallHistoryModel*>();
if( mFilterFlags > 0) {
show = ( ((mFilterFlags & CallTimelineFilter::Incoming) == CallTimelineFilter::Incoming) && !timeline->mLastCallIsOutgoing)
|| ( ((mFilterFlags & CallTimelineFilter::Outgoing) == CallTimelineFilter::Outgoing) && timeline->mLastCallIsOutgoing)
|| ( ((mFilterFlags & CallTimelineFilter::Missed) == CallTimelineFilter::Missed) && timeline->mLastCallStatus == LinphoneEnums::CallStatusMissed)
;
}
if(show && mFilterText != ""){
QRegularExpression search(QRegularExpression::escape(mFilterText), QRegularExpression::CaseInsensitiveOption | QRegularExpression::UseUnicodePropertiesOption);
show = ( timeline->getTitle().contains(search)
//|| timeline->getRemoteAddress().contains(search)
|| Utils::getDisplayName(timeline->getRemoteAddress()).contains(search)
);
//|| timeline->getChatRoomModel()->getFullPeerAddress().contains(search); not enough significant?
}
return show;
}
bool CallHistoryProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
if( !sourceModel())
return false;
const CallHistoryModel* a = sourceModel()->data(left).value<CallHistoryModel*>();
const CallHistoryModel* b = sourceModel()->data(right).value<CallHistoryModel*>();
return a->mLastCallDate > b->mLastCallDate;
}
static inline QWindow *getParentWindow (QObject *object) {
App *app = App::getInstance();
const QWindow *mainWindow = app->getMainWindow();
const QWindow *callsWindow = app->getCallsWindow();
for (QObject *parent = object->parent(); parent; parent = parent->parent())
if (parent == mainWindow || parent == callsWindow)
return static_cast<QWindow *>(parent);
return nullptr;
}
void CallHistoryProxyModel::handleIsActiveChanged (QWindow *window) {
if (window->isActive() && getParentWindow(this) == window) {
CoreManager::getInstance()->resetMissedCallsCount();
}
}

View file

@ -0,0 +1,70 @@
/*
* Copyright (c) 2020-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CALL_HISTORY_PROXY_MODEL_H_
#define CALL_HISTORY_PROXY_MODEL_H_
#include <QSortFilterProxyModel>
#include <memory>
class CallHistoryModel;
class QWindow;
// =============================================================================
class CallHistoryProxyModel : public QSortFilterProxyModel {
Q_OBJECT
public:
CallHistoryProxyModel (QObject *parent = Q_NULLPTR);
enum CallTimelineFilter {
Incoming = 1,
Outgoing = 2,
Missed = 4,
All = 0
};
Q_ENUM(CallTimelineFilter)
Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
void setFilterFlags(int flags);
Q_INVOKABLE void setFilterText(const QString& text);
void handleIsActiveChanged (QWindow *window);
signals:
void countChanged();
void filterTextChanged();
void selectedChanged(const QString& remoteAddress);
void filterFlagsChanged();
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
private:
QString mFilterText;
int mFilterFlags = -1;
};
#endif

View file

@ -31,8 +31,10 @@
#include <QUrlQuery>
#include <QImageReader>
#include "CallHistoryModel.hpp"
#include "components/core/CoreHandlers.hpp"
#include "components/core/CoreManager.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "utils/Utils.hpp"
#include "HistoryModel.hpp"
@ -83,10 +85,19 @@ HistoryModel::HistoryModel (QObject *parent) :QAbstractListModel(parent){
setSipAddresses();
CoreHandlers *coreHandlers = mCoreHandlers.get();
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged);
}
HistoryModel::HistoryModel (CallHistoryModel * callHistoryModel, QObject *parent) :QAbstractListModel(parent){
CoreManager *coreManager = CoreManager::getInstance();
mCoreHandlers = coreManager->getHandlers();
setSipAddresses(callHistoryModel);
CoreHandlers *coreHandlers = mCoreHandlers.get();
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &HistoryModel::handleCallStateChanged);
}
HistoryModel::~HistoryModel () {
qWarning() << "Destroying HistoryModel";
}
QHash<int, QByteArray> HistoryModel::roleNames () const {
@ -148,23 +159,110 @@ bool HistoryModel::removeRows (int row, int count, const QModelIndex &parent) {
return true;
}
void HistoryModel::setSipAddresses () {
static bool hasSameParameters(const QStringList& a, const QStringList& b){
if(a.size() != b.size())
return false;
int i = 0;
while(i < a.size()) {
if(b.contains(a[i]))
++i;
else
break;
}
return i >= a.size();
}
// Why complicated?
// - Address parameters can be stored in different order and getCallHistory() reorder address parameters => need to get on pure address without parameters.
// - A call to/from someone (no gruu and no conf-id) can a conference call => the pair remotre address + URI need to be check (watchout of parameters order)
void HistoryModel::setSipAddresses (CallHistoryModel *callModel) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
beginResetModel();
mEntries.clear();
QElapsedTimer timer;
timer.start();
// Get calls.
for (auto &callLog : core->getCallLogs())
insertCall(callLog);
if(!callModel)
for (auto &callLog : core->getCallLogs())
insertCall(callLog);
else{
mRemoteAddress = callModel->getRemoteAddress();
auto address = Utils::interpretUrl(mRemoteAddress);// already cleaned
auto conferenceInfoModel = callModel->getConferenceInfoModel();
QStringList conferenceInfoModelParams;
if(conferenceInfoModel) {
mConferenceUri = conferenceInfoModel->getUri();
conferenceInfoModelParams = mConferenceUri.split(";");
}
for (auto &callLog : core->getCallHistory(address, CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
bool toInsert = false;
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
/*
QString uriOnly = Utils::coreStringToAppString(address->asStringUriOnly());
QStringList parameters = uriOnly.split(";");
auto conferenceInfoModel = callModel->getConferenceInfoModel();
QStringList conferenceInfoModelParams;
if(conferenceInfoModel) {
conferenceInfoModelParams = conferenceInfoModel->getUri().split(";");
}
for (auto &callLog : core->getCallHistory(Utils::interpretUrl(parameters[0]), CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
if(parameters.size() > 2) { // We have to check address with mixed parameters order from the result of getCallHistory()
for (auto &callLog : core->getCallHistory(Utils::interpretUrl(parameters[0]), CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
QStringList logParams = Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()).split(";");
if(hasSameParameters(parameters, logParams)) {// Remote address are equal
bool toInsert = false;
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
}
}else {
for (auto &callLog : core->getCallHistory(address, CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
bool toInsert = false;
if(conferenceInfoModel && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(!conferenceInfoModel && !callLogConferenceInfoModel)
toInsert = true;
if(toInsert)
insertCall(callLog);
}
}*/
}
qInfo() << QStringLiteral("HistoryModel loaded in %3 milliseconds.").arg(timer.elapsed());
endResetModel();
}
void HistoryModel::reload(){
beginResetModel();
setSipAddresses();
//setSipAddresses();
endResetModel();
}
// -----------------------------------------------------------------------------
@ -267,7 +365,25 @@ void HistoryModel::resetMessageCount () {
// -----------------------------------------------------------------------------
void HistoryModel::handleCallStateChanged (const shared_ptr<linphone::Call> &call, linphone::Call::State state) {
if (state == linphone::Call::State::End || state == linphone::Call::State::Error)
insertCall(call->getCallLog());
if (state == linphone::Call::State::End || state == linphone::Call::State::Error) {
auto address = Utils::interpretUrl(mRemoteAddress);// already cleaned
QStringList conferenceInfoModelParams = mConferenceUri.split(";");
bool toInsert = false;
auto callLog = call->getCallLog();
auto callLogConferenceInfoModel = callLog->getConferenceInfo();
if(mRemoteAddress.isEmpty())
toInsert = true;
else if(address->weakEqual(callLog->getRemoteAddress()) && callLog->getLocalAddress()->weakEqual(CoreManager::getInstance()->getAccountSettingsModel()->getUsedSipAddress())) {
if(!mConferenceUri.isEmpty() && callLogConferenceInfoModel) {
QStringList logConfUriParams = Utils::coreStringToAppString(callLogConferenceInfoModel->getUri()->asStringUriOnly()).split(";");
if(hasSameParameters(conferenceInfoModelParams, logConfUriParams)) {// Uri addresses are equal
toInsert = true;
}
}else if(mConferenceUri.isEmpty() && !callLogConferenceInfoModel)
toInsert = true;
}
if(toInsert)
insertCall(callLog);
}
}

View file

@ -30,6 +30,7 @@
// =============================================================================
class CoreHandlers;
class CallHistoryModel;
class HistoryModel : public QAbstractListModel {
@ -59,6 +60,7 @@ public:
Q_ENUM(CallStatus)
HistoryModel (QObject *parent = Q_NULLPTR);
HistoryModel (CallHistoryModel *callHistoryModel, QObject *parent = Q_NULLPTR);
virtual ~HistoryModel ();
int rowCount (const QModelIndex &index = QModelIndex()) const override;
@ -72,6 +74,8 @@ public:
void removeEntry (int id);
void removeAllEntries ();
void setSipAddresses (CallHistoryModel * callModel = nullptr);
void resetMessageCount ();
Q_INVOKABLE void reload();
@ -86,13 +90,14 @@ signals:
private:
typedef QPair<QVariantMap, std::shared_ptr<void>> HistoryEntryData;
void setSipAddresses ();
void removeEntry (HistoryEntryData &entry);
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
void handleCallStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::Call::State state);
mutable QList<HistoryEntryData> mEntries;
QString mRemoteAddress;
QString mConferenceUri;
QSharedPointer<CoreHandlers> mCoreHandlers;
};

View file

@ -24,6 +24,7 @@
#include "components/core/CoreManager.hpp"
#include "HistoryProxyModel.hpp"
#include "CallHistoryModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
// =============================================================================
@ -55,6 +56,13 @@ protected:
return data["type"].toInt() == mEntryTypeFilter;
}
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override {
if( !sourceModel())
return false;
auto a = sourceModel()->data(left).value<QVariantMap>();
auto b = sourceModel()->data(right).value<QVariantMap>();
return a["receivedTimestamp"] > b["receivedTimestamp"];
}
private:
HistoryModel::EntryType mEntryTypeFilter = HistoryModel::EntryType::GenericEntry;
};
@ -64,8 +72,7 @@ private:
HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(new HistoryModelFilter(this));
reload();
sort(0);
App *app = App::getInstance();
QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
handleIsActiveChanged(App::getInstance()->getMainWindow());
@ -78,20 +85,22 @@ HistoryProxyModel::HistoryProxyModel (QObject *parent) : QSortFilterProxyModel(p
});
}
void HistoryProxyModel::setCallHistoryModel(CallHistoryModel * model) {
if(mCallHistoryModel != model){
mCallHistoryModel = model;
reload();
emit callHistoryModelChanged();
}
}
// -----------------------------------------------------------------------------
void HistoryProxyModel::removeAllEntries(){
auto model = CoreManager::getInstance()->getHistoryModel();
if (!model)
return;
model->removeAllEntries();
static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->removeAllEntries();
emit mCallHistoryModel->hasBeenRemoved();
}
void HistoryProxyModel::removeEntry (int id){
auto model = CoreManager::getInstance()->getHistoryModel();
if (!model)
return;
QModelIndex sourceIndex = mapToSource(index(id, 0));
model->removeEntry(static_cast<HistoryModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() );
static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->removeEntry(static_cast<HistoryModelFilter *>(sourceModel())->mapToSource(sourceIndex).row() );
}
// -----------------------------------------------------------------------------
@ -128,19 +137,31 @@ bool HistoryProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &) co
return sourceModel()->rowCount() - sourceRow <= mMaxDisplayedEntries;
}
bool HistoryProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const{
if( !sourceModel())
return false;
auto a = sourceModel()->data(left).value<QVariantMap>();
auto b = sourceModel()->data(right).value<QVariantMap>();
return a["receivedTimestamp"] > b["receivedTimestamp"];
}
// -----------------------------------------------------------------------------
void HistoryProxyModel::reload () {
mMaxDisplayedEntries = EntriesChunkSize;
auto model = CoreManager::getInstance()->getHistoryModel();
//auto model = CoreManager::getInstance()->getHistoryModel();
//model->reload();
static_cast<HistoryModelFilter *>(sourceModel())->setSourceModel(model);
static_cast<HistoryModelFilter *>(sourceModel())->setSourceModel(new HistoryModel(mCallHistoryModel));
invalidate();
}
void HistoryProxyModel::resetMessageCount(){
static_cast<HistoryModel*>(static_cast<HistoryModelFilter *>(sourceModel())->sourceModel())->resetMessageCount();
/*
auto model = CoreManager::getInstance()->getHistoryModel();
if( model){
model->resetMessageCount();
}
*/
}
// -----------------------------------------------------------------------------

View file

@ -32,11 +32,14 @@ class QWindow;
class HistoryProxyModel : public QSortFilterProxyModel {
class HistoryModelFilter;
Q_OBJECT;
Q_OBJECT
public:
Q_PROPERTY(CallHistoryModel *callHistoryModel MEMBER mCallHistoryModel WRITE setCallHistoryModel NOTIFY callHistoryModelChanged)
HistoryProxyModel (QObject *parent = Q_NULLPTR);
void setCallHistoryModel(CallHistoryModel * model);
Q_INVOKABLE void loadMoreEntries ();
Q_INVOKABLE void setEntryTypeFilter (HistoryModel::EntryType type = HistoryModel::EntryType::CallEntry);
Q_INVOKABLE void removeEntry (int id);
@ -48,17 +51,18 @@ public:
Q_INVOKABLE void reload();
signals:
void moreEntriesLoaded (int n);
void entryTypeFilterChanged (HistoryModel::EntryType type);
void callHistoryModelChanged();
protected:
bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
private:
void handleIsActiveChanged (QWindow *window);
CallHistoryModel * mCallHistoryModel = nullptr;
int mMaxDisplayedEntries = EntriesChunkSize;

View file

@ -155,6 +155,8 @@ class ColorListModel : public ProxyListModel {
ADD_COLOR("progress_bg", "black", "Background of round progress bar")
ADD_COLOR("progress_remaining_fg", "white", "Remaining progression color")
ADD_COLOR("timeline_header_bg", "#E1E4E7", "Header Timeline background")
ADD_COLOR("timeline_bg_1", "#EFF0F2", "Timeline background color 1")
ADD_COLOR("timeline_bg_2", "#FFFFFF", "Timeline background color 2")

View file

@ -23,6 +23,7 @@
#include <QImageReader>
#include <QPainter>
#include <QMediaPlayer>
#include <QSvgRenderer>
#include "app/App.hpp"
#include "utils/Utils.hpp"
@ -88,22 +89,36 @@ QImage ImageModel::createThumbnail(const QString& path, QImage originalImage){
QExifImageHeader exifImageHeader;
if (exifImageHeader.loadFromJpeg(path))
rotation = int(exifImageHeader.value(QExifImageHeader::ImageTag::Orientation).toShort());
// Fill with color to replace transparency with white color instead of black (default).
QImage image(originalImage.size(), originalImage.format());
image.fill(QColor(Qt::white).rgb());
QPainter painter(&image);
painter.drawImage(0, 0, originalImage);
//--------------------
double factor = image.width() / (double)image.height();
double factor = originalImage.width() / (double)originalImage.height();
Qt::AspectRatioMode aspectRatio = Qt::KeepAspectRatio;
if(factor < 0.2 || factor > 5)
aspectRatio = Qt::KeepAspectRatioByExpanding;
thumbnail = image.scaled(
Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight,
aspectRatio , Qt::SmoothTransformation
);
if(aspectRatio == Qt::KeepAspectRatioByExpanding)
thumbnail = thumbnail.copy(0,0,Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight);
QImageReader reader(path);
if(reader.format() == "svg"){
QSvgRenderer svgRenderer(path);
if(svgRenderer.isValid()){
thumbnail = QImage(Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight, originalImage.format());
thumbnail.fill(QColor(Qt::transparent));
QPainter painter(&thumbnail);
svgRenderer.setAspectRatioMode(aspectRatio);
svgRenderer.render(&painter);
}
}
if(thumbnail.isNull()){
QImage image(originalImage.size(), originalImage.format());
// Fill with color to replace transparency with white color instead of black (default).
image.fill(QColor(Qt::white).rgb());
QPainter painter(&image);
painter.drawImage(0, 0, originalImage);
//--------------------
thumbnail = image.scaled(
Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight,
aspectRatio , Qt::SmoothTransformation
);
if(aspectRatio == Qt::KeepAspectRatioByExpanding)// Cut
thumbnail = thumbnail.copy(0,0,Constants::ThumbnailImageFileWidth, Constants::ThumbnailImageFileHeight);
}
if (rotation != 0) {
QTransform transform;

View file

@ -58,10 +58,9 @@ static inline AccountSettingsModel::RegistrationState mapLinphoneRegistrationSta
AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
CoreManager *coreManager = CoreManager::getInstance();
QObject::connect(
coreManager->getHandlers().get(), &CoreHandlers::registrationStateChanged,
this, &AccountSettingsModel::handleRegistrationStateChanged
);
QObject::connect(coreManager->getHandlers().get(), &CoreHandlers::registrationStateChanged, this, &AccountSettingsModel::handleRegistrationStateChanged);
QObject::connect(coreManager, &CoreManager::callLogsCountChanged, this, &AccountSettingsModel::missedCallsCountChanged);
//QObject::connect(coreManager, &CoreManager::eventCountChanged, this, [this]() { emit accountSettingsUpdated(); });
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::usernameChanged);
@ -75,6 +74,8 @@ AccountSettingsModel::AccountSettingsModel (QObject *parent) : QObject(parent) {
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primaryUsernameChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::primarySipAddressChanged);
QObject::connect(this, &AccountSettingsModel::accountSettingsUpdated, this, &AccountSettingsModel::accountsChanged);
QObject::connect(this, &AccountSettingsModel::accountsChanged, this, &AccountSettingsModel::missedCallsCountChanged);
QObject::connect(this, &AccountSettingsModel::accountsChanged, this, &AccountSettingsModel::unreadMessagesCountChanged);
mSelectedAccount = coreManager->getCore()->getDefaultAccount();
}
@ -251,6 +252,19 @@ bool AccountSettingsModel::getUseInternationalPrefixForCallsAndChats() const{
return false;
}
int AccountSettingsModel::getMissedCallsCount() const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Account> account = core->getDefaultAccount();
return account ? account->getMissedCallsCount() : core->getMissedCallsCount();
}
int AccountSettingsModel::getUnreadMessagesCount() const {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
shared_ptr<linphone::Account> account = core->getDefaultAccount();
return account ? account->getUnreadChatMessageCount() : core->getUnreadChatMessageCount();
}
void AccountSettingsModel::setDefaultAccount (const shared_ptr<linphone::Account> &account) {
shared_ptr<linphone::Core> core = CoreManager::getInstance()->getCore();
if (mSelectedAccount != account) {
@ -602,8 +616,8 @@ QVariantList AccountSettingsModel::getAccounts () const {
QVariantMap account;
account["sipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asStringUriOnly());
account["fullSipAddress"] = Utils::coreStringToAppString(core->createPrimaryContactParsed()->asString());
account["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? core->getUnreadChatMessageCountFromLocal(core->createPrimaryContactParsed()) : 0;
account["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(account["sipAddress"].toString());
account["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? core->getUnreadChatMessageCount() : 0;
account["missedCallCount"] = core->getMissedCallsCount();
account["account"].setValue(nullptr);
accounts << account;
}
@ -615,7 +629,7 @@ QVariantList AccountSettingsModel::getAccounts () const {
accountMap["fullSipAddress"] = Utils::coreStringToAppString(params->getIdentityAddress()->asString());
accountMap["account"].setValue(account);
accountMap["unreadMessageCount"] = settingsModel->getStandardChatEnabled() || settingsModel->getSecureChatEnabled() ? account->getUnreadChatMessageCount() : 0;
accountMap["missedCallCount"] = CoreManager::getInstance()->getMissedCallCountFromLocal(accountMap["sipAddress"].toString());
accountMap["missedCallCount"] = account->getMissedCallsCount();
accountMap["registerEnabled"] = params->registerEnabled();
accounts << accountMap;
}

View file

@ -51,6 +51,9 @@ class AccountSettingsModel : public QObject {
Q_PROPERTY(QString defaultAccountDomain READ getDefaultAccountDomain NOTIFY defaultAccountChanged)
Q_PROPERTY(QVariantList accounts READ getAccounts NOTIFY accountsChanged)
Q_PROPERTY(int missedCallsCount READ getMissedCallsCount NOTIFY missedCallsCountChanged)
Q_PROPERTY(int unreadMessagesCount READ getUnreadMessagesCount NOTIFY unreadMessagesCountChanged)
public:
enum RegistrationState {
@ -80,6 +83,8 @@ public:
QString getVideoConferenceUri() const;
QString getLimeServerUrl() const;
bool getUseInternationalPrefixForCallsAndChats() const;
int getMissedCallsCount() const;
int getUnreadMessagesCount() const;
Q_INVOKABLE void setDefaultAccount (const std::shared_ptr<linphone::Account> &account = nullptr);
Q_INVOKABLE void setDefaultAccountFromSipAddress (const QString &sipAddress);
@ -120,6 +125,8 @@ signals:
void defaultAccountChanged();
void publishPresenceChanged();
void defaultRegistrationChanged();
void missedCallsCountChanged();
void unreadMessagesCountChanged();
private:
QString getUsername () const;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -50,11 +50,3 @@ void SipAddressObserver::setPresenceTimestamp(const QDateTime &presenceTimestamp
mPresenceTimestamp = presenceTimestamp;
emit presenceTimestampChanged(presenceTimestamp);
}
void SipAddressObserver::setUnreadMessageCount (int unreadMessageCount) {
if (unreadMessageCount == mUnreadMessageCount)
return;
mUnreadMessageCount = unreadMessageCount;
emit unreadMessageCountChanged(unreadMessageCount);
}

View file

@ -41,7 +41,6 @@ class SipAddressObserver : public QObject {
Q_PROPERTY(ContactModel *contact READ getContact NOTIFY contactChanged);
Q_PROPERTY(Presence::PresenceStatus presenceStatus READ getPresenceStatus NOTIFY presenceStatusChanged);
Q_PROPERTY(QDateTime presenceTimestamp READ getPresenceTimestamp NOTIFY presenceTimestampChanged);
Q_PROPERTY(int unreadMessageCount READ getUnreadMessageCount NOTIFY unreadMessageCountChanged);
Q_PROPERTY(bool isOneToOne MEMBER isOneToOne CONSTANT);
Q_PROPERTY(bool haveEncryption MEMBER haveEncryption CONSTANT);
@ -57,7 +56,6 @@ signals:
void contactChanged (QSharedPointer<ContactModel>);
void presenceStatusChanged (const Presence::PresenceStatus &presenceStatus);
void presenceTimestampChanged (const QDateTime &presenceTimestamp);
void unreadMessageCountChanged (int unreadMessageCount);
private:
QString getPeerAddress () const {
@ -89,20 +87,12 @@ private:
void setPresenceTimestamp (const QDateTime &presenceTimestamp);
// ---------------------------------------------------------------------------
int getUnreadMessageCount () const {
return mUnreadMessageCount;
}
void setUnreadMessageCount (int unreadMessageCount);
QString mPeerAddress;
QString mLocalAddress;
QSharedPointer<ContactModel> mContact;
Presence::PresenceStatus mPresenceStatus = Presence::PresenceStatus::Offline;
QDateTime mPresenceTimestamp;
int mUnreadMessageCount = 0;
};
Q_DECLARE_METATYPE(SipAddressObserver *);

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -177,10 +177,6 @@ SipAddressObserver *SipAddressesModel::getSipAddressObserver (const QString &pee
model->setContact(it->contact);
model->setPresenceStatus(it->presenceStatus);
model->setPresenceTimestamp(it->presenceTimestamp);
auto it2 = it->localAddressToConferenceEntry.find(cleanedLocalAddress);
if (it2 != it->localAddressToConferenceEntry.end())
model->setUnreadMessageCount(it2->unreadMessageCount+it2->missedCallCount);
}
mObservers.insert(cleanedPeerAddress, model);
@ -327,17 +323,11 @@ void SipAddressesModel::handleChatRoomModelCreated (const QSharedPointer<ChatRoo
QObject::connect(ptr, &ChatRoomModel::lastEntryRemoved, this, [this, ptr] {
handleLastEntryRemoved(ptr);
});
QObject::connect(ptr, &ChatRoomModel::messageCountReset, this, [this, ptr] {
handleMessageCountReset(ptr);
});
QObject::connect(ptr, &ChatRoomModel::messageSent, this, &SipAddressesModel::handleMessageSent);
}
void SipAddressesModel::handleHistoryModelCreated (HistoryModel *historyModel) {
QObject::connect(historyModel, &HistoryModel::callCountReset, this, [this] {
handleAllCallCountReset();
});
}
void SipAddressesModel::handleContactAdded (QSharedPointer<ContactModel> contact) {
@ -485,38 +475,6 @@ void SipAddressesModel::handleLastEntryRemoved (ChatRoomModel *chatRoomModel) {
emit dataChanged(index(row, 0), index(row, 0));
}
void SipAddressesModel::handleAllCallCountReset () {
for( auto peer = mPeerAddressToSipAddressEntry.begin() ; peer != mPeerAddressToSipAddressEntry.end() ; ++peer){
for( auto local = peer->localAddressToConferenceEntry.begin() ; local != peer->localAddressToConferenceEntry.end() ; ++local){
local->missedCallCount = 0;
updateObservers(peer.key(), local.key(), local->unreadMessageCount, local->missedCallCount);
}
int row = mRefs.indexOf(&(*peer));
emit dataChanged(index(row, 0), index(row, 0));
}
}
void SipAddressesModel::handleMessageCountReset (ChatRoomModel *chatRoomModel) {
const QString &peerAddress = Utils::cleanSipAddress(chatRoomModel->getPeerAddress());
auto it = mPeerAddressToSipAddressEntry.find(peerAddress);
if (it == mPeerAddressToSipAddressEntry.end())
return;
const QString &localAddress = Utils::cleanSipAddress(chatRoomModel->getLocalAddress());
auto it2 = it->localAddressToConferenceEntry.find(localAddress);
if (it2 == it->localAddressToConferenceEntry.end())
return;
it2->unreadMessageCount = 0;
it2->missedCallCount = 0;
int row = mRefs.indexOf(&(*it));
Q_ASSERT(row != -1);
emit dataChanged(index(row, 0), index(row, 0));
updateObservers(peerAddress, localAddress, 0, 0);
}
void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &message) {
if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){
auto lPeerAddress = message->getChatRoom()->getPeerAddress();
@ -573,12 +531,10 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry,
conferenceEntry.timestamp = callLog->getStatus() == linphone::Call::Status::Success
? QDateTime::fromMSecsSinceEpoch((callLog->getStartDate() + callLog->getDuration()) * 1000)
: QDateTime::fromMSecsSinceEpoch(callLog->getStartDate() * 1000);
conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress);
QString oldDisplayName = sipAddressEntry.displayNames.get();
sipAddressEntry.displayNames.updateFromCall(lPeerAddress);
if(oldDisplayName != sipAddressEntry.displayNames.get())
emit CoreManager::getInstance()->getContactsListModel()->contactUpdated(nullptr);
updateObservers(sipAddressEntry.sipAddress, localAddress, conferenceEntry.unreadMessageCount,conferenceEntry.missedCallCount);
}
void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry, const shared_ptr<linphone::ChatMessage> &message) {
@ -595,10 +551,7 @@ void SipAddressesModel::addOrUpdateSipAddress (SipAddressEntry &sipAddressEntry,
ConferenceEntry &conferenceEntry = sipAddressEntry.localAddressToConferenceEntry[localAddress];
conferenceEntry.timestamp = QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000);
conferenceEntry.unreadMessageCount = count ;
conferenceEntry.missedCallCount = CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress);
sipAddressEntry.displayNames.updateFromChatMessage(lPeerAddress);
updateObservers(sipAddressEntry.sipAddress, localAddress, count,conferenceEntry.missedCallCount);
}
template<typename T>
@ -685,8 +638,6 @@ void SipAddressesModel::initSipAddressesFromChat () {
QString localAddress(Utils::cleanSipAddress(Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly())));
getSipAddressEntry(peerAddress, lPeerAddress)->localAddressToConferenceEntry[localAddress] = {
chatRoom->getUnreadMessagesCount(),
CoreManager::getInstance()->getMissedCallCount(peerAddress, localAddress),
false,
QDateTime::fromMSecsSinceEpoch(lastMessage->getTime() * 1000)
};
@ -716,7 +667,7 @@ void SipAddressesModel::initSipAddressesFromCalls () {
auto &localToConferenceEntry = sipAddressEntry->localAddressToConferenceEntry;
auto it = localToConferenceEntry.find(localAddress);
if (it == localToConferenceEntry.end()) {
localToConferenceEntry[localAddress] = { 0,0, false, move(timestamp) };
localToConferenceEntry[localAddress] = { false, move(timestamp) };
sipAddressEntry->displayNames.mFromCallLogs = QString::fromStdString(callLog->getRemoteAddress()->getDisplayName());
}else if (it->timestamp.isNull() || timestamp > it->timestamp){
it->timestamp = move(timestamp);
@ -747,13 +698,4 @@ void SipAddressesModel::updateObservers (const QString &sipAddress, const Presen
observer->setPresenceStatus(presenceStatus);
observer->setPresenceTimestamp(presenceTimestamp);
}
}
void SipAddressesModel::updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount) {
for (auto &observer : mObservers.values(peerAddress)) {
if (observer->getLocalAddress() == localAddress) {
observer->setUnreadMessageCount(messageCount+missedCallCount);
return;
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -37,12 +37,10 @@ class CoreHandlers;
class HistoryModel;
class SipAddressesModel : public QAbstractListModel {
Q_OBJECT;
Q_OBJECT
public:
struct ConferenceEntry {
int unreadMessageCount;
int missedCallCount;
bool isComposing;
QDateTime timestamp;
};
@ -81,8 +79,6 @@ public:
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
//Q_PROPERTY(QList<QVariant> resultExceptions READ getResultExceptions WRITE setResultExceptions NOTIFY resultExceptionsChanged)
Q_INVOKABLE QVariantMap find (const QString &sipAddress) const;
Q_INVOKABLE ContactModel *mapSipAddressToContact (const QString &sipAddress) const;
Q_INVOKABLE SipAddressObserver *getSipAddressObserver (const QString &peerAddress, const QString &localAddress);
@ -113,9 +109,6 @@ public:
signals:
void sipAddressReset();// The model has been reset
public slots:
void handleAllCallCountReset ();
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
@ -140,8 +133,6 @@ private:
void handleAllEntriesRemoved (ChatRoomModel *chatRoomModel);
void handleLastEntryRemoved (ChatRoomModel *chatRoomModel);
void handleMessageCountReset (ChatRoomModel *chatRoomModel);
void handleMessageSent (const std::shared_ptr<linphone::ChatMessage> &message);
void handleIsComposingChanged (const std::shared_ptr<linphone::ChatRoom> &chatRoom);
@ -166,7 +157,6 @@ private:
void updateObservers (const QString &sipAddress, QSharedPointer<ContactModel> contact);
void updateObservers (const QString &sipAddress, const Presence::PresenceStatus &presenceStatus, const QDateTime &presenceTimestamp);
void updateObservers (const QString &peerAddress, const QString &localAddress, int messageCount, int missedCallCount);
// ---------------------------------------------------------------------------

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).
@ -25,8 +25,6 @@
#include "components/calls/CallsListModel.hpp"
#include "components/settings/AccountSettingsModel.hpp"
#include "components/settings/SettingsModel.hpp"
#include "components/sip-addresses/SipAddressesModel.hpp"
#include "components/contacts/ContactsListModel.hpp"
#include "utils/Utils.hpp"
@ -327,7 +325,6 @@ void TimelineListModel::updateTimelines () {
qInfo() << "Timelines adding :" << stepsTimer.restart() << "ms for " << models.size() << " new timelines";
add(models);
qInfo() << "Timelines adding GUI :" << stepsTimer.restart() << "ms.";
CoreManager::getInstance()->updateUnreadMessageCount();
qInfo() << "Timelines initialized in:" << timer.elapsed() << "ms.";
}
@ -460,7 +457,6 @@ void TimelineListModel::onCallCreated(const std::shared_ptr<linphone::Call> &cal
}
if(!found){// Create a default chat room
QVariantList participants;
//participants << Utils::coreStringToAppString(callLog->getRemoteAddress()->asStringUriOnly()); // This allow chatting to a specific device but the current design is not adapted to show them
auto remoteAddress = callLog->getRemoteAddress()->clone();
remoteAddress->clean();
participants << Utils::coreStringToAppString(remoteAddress->asStringUriOnly());

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2020 Belledonne Communications SARL.
* Copyright (c) 2010-2023 Belledonne Communications SARL.
*
* This file is part of linphone-desktop
* (see https://www.linphone.org).

View file

@ -61,6 +61,13 @@ void TimelineProxyModel::setFilterText(const QString& text){
emit filterTextChanged();
}
}
void TimelineProxyModel::setMode(const TimelineMode& mode) {
if(mMode != mode) {
mMode = mode;
emit modeChanged();
}
}
TimelineProxyModel::TimelineListSource TimelineProxyModel::getListSource() const{
return mListSource;
@ -115,15 +122,12 @@ bool TimelineProxyModel::filterAcceptsRow (int sourceRow, const QModelIndex &sou
return false;
bool show = (mFilterFlags==0);// Show all at 0 (no hide all)
bool isGroup = timeline->getChatRoomModel()->isGroupEnabled();
bool isEphemeral = timeline->getChatRoomModel()->isEphemeralEnabled();
if( mFilterFlags > 0) {
show = !(( ( (mFilterFlags & TimelineFilter::SimpleChatRoom) == TimelineFilter::SimpleChatRoom) && isGroup)
|| ( ( (mFilterFlags & TimelineFilter::SecureChatRoom) == TimelineFilter::SecureChatRoom) && !haveEncryption)
|| ( ( (mFilterFlags & TimelineFilter::GroupChatRoom) == TimelineFilter::GroupChatRoom) && !isGroup)
|| ( ( (mFilterFlags & TimelineFilter::StandardChatRoom) == TimelineFilter::StandardChatRoom) && haveEncryption)
|| ( ( (mFilterFlags & TimelineFilter::EphemeralChatRoom) == TimelineFilter::EphemeralChatRoom) && !isEphemeral)
|| ( ( (mFilterFlags & TimelineFilter::NoEphemeralChatRoom) == TimelineFilter::NoEphemeralChatRoom) && isEphemeral));
show = !(
( ((mFilterFlags & TimelineFilter::SecureChatRoom) == TimelineFilter::SecureChatRoom) && !haveEncryption)
|| ( ((mFilterFlags & TimelineFilter::GroupChatRoom) == TimelineFilter::GroupChatRoom) && !isGroup)
);
}
if(show && mFilterText != ""){
@ -142,8 +146,8 @@ bool TimelineProxyModel::lessThan (const QModelIndex &left, const QModelIndex &r
return false;
const TimelineModel* a = sourceModel()->data(left).value<TimelineModel*>();
const TimelineModel* b = sourceModel()->data(right).value<TimelineModel*>();
bool aHaveUnread = a->getChatRoomModel()->getAllUnreadCount() > 0;
bool bHaveUnread = b->getChatRoomModel()->getAllUnreadCount() > 0;
bool aHaveUnread = a->getChatRoomModel()->getUnreadMessagesCount() > 0;
bool bHaveUnread = b->getChatRoomModel()->getUnreadMessagesCount() > 0;
return (aHaveUnread && !bHaveUnread)
|| (aHaveUnread == bHaveUnread && a->getChatRoomModel()->mLastUpdateTime > b->getChatRoomModel()->mLastUpdateTime);
}

View file

@ -34,18 +34,19 @@ class TimelineProxyModel : public QSortFilterProxyModel {
public:
enum TimelineFilter {
StandardChatRoom=1,
SecureChatRoom=2,
SimpleChatRoom=4,
GroupChatRoom=8,
EphemeralChatRoom=16,
NoEphemeralChatRoom=32,
SecureChatRoom = 1,
GroupChatRoom = 2,
AllChatRooms = 0
};
Q_ENUM(TimelineFilter)
enum TimelineListSource{
enum TimelineMode {
Chats,
Calls
};
Q_ENUM(TimelineMode)
enum TimelineListSource{
Undefined,
Main, // Timeline list comes from the singleton stored in CoreManager.
Copy // Timeline list is created from Main but have no attach to the main list (aside of root items).
@ -59,10 +60,12 @@ public:
Q_PROPERTY(int filterFlags MEMBER mFilterFlags WRITE setFilterFlags NOTIFY filterFlagsChanged)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(TimelineMode mode MEMBER mMode WRITE setMode NOTIFY modeChanged)
Q_INVOKABLE void unselectAll();
Q_INVOKABLE void setFilterFlags(const int& filterFlags);
Q_INVOKABLE void setFilterText(const QString& text);
Q_INVOKABLE void setMode(const TimelineMode& mode);
TimelineListSource getListSource() const;
void setListSource(const TimelineListSource& source);
@ -74,6 +77,7 @@ signals:
void filterFlagsChanged();
void filterTextChanged();
void listSourceChanged();
void modeChanged();
protected:
@ -87,6 +91,7 @@ protected:
private:
int mFilterFlags = 0;
QString mFilterText;
TimelineMode mMode = Chats;
TimelineListSource mListSource = Undefined;
};

View file

@ -119,11 +119,11 @@ QDateTime Utils::getOffsettedUTC(const QDateTime& date){
return utc;
}
QString Utils::toDateTimeString(QDateTime date){
QString Utils::toDateTimeString(QDateTime date, const QString& format){
if(date.date() == QDate::currentDate())
return toTimeString(date);
else{
return getOffsettedUTC(date).toString("yyyy/MM/dd hh:mm:ss");
return getOffsettedUTC(date).toString(format);
}
}
@ -223,7 +223,8 @@ bool Utils::isGreatherThan(const QDate& d1, const QDate& d2) {
//--------------------------------------------------------------------------------------
QString Utils::getDisplayName(const QString& address){
return getDisplayName(interpretUrl(address));
QString displayName = getDisplayName(interpretUrl(address));
return displayName.isEmpty() ? address : displayName;
}
QString Utils::getInitials(const QString& username){

View file

@ -68,7 +68,7 @@ public:
//***** DATE TIME
Q_INVOKABLE static QDateTime addMinutes(QDateTime date, const int& min);
static QDateTime getOffsettedUTC(const QDateTime& date);
Q_INVOKABLE static QString toDateTimeString(QDateTime date);
Q_INVOKABLE static QString toDateTimeString(QDateTime date, const QString& format = "yyyy/MM/dd hh:mm:ss");
Q_INVOKABLE static QString toTimeString(QDateTime date, const QString& format = "hh:mm:ss");
Q_INVOKABLE static QString toDateString(QDateTime date, const QString& format = "");
Q_INVOKABLE static QString toDateString(QDate date, const QString& format = "");

View file

@ -30,7 +30,7 @@ Item {
image.colorOverwriteEnabled = false
height: iconHeight > 0 ? iconHeight : iconSize
width: iconWidth > 0 ? iconWidth : iconSize
visible: icon != ''
Image {
id:image
anchors.fill: parent

View file

@ -9,8 +9,10 @@ import Common.Styles 1.0
Controls.Menu {
id: menu
property var menuStyle : MenuStyle.normal
property alias radius: brackgroundArea.radius
width: menuStyle.width ? menuStyle.width : parent.width
background: Rectangle {
id: brackgroundArea
implicitWidth: menu.width
color: menuStyle.colorModel.color
radius: menuStyle.radius

View file

@ -17,18 +17,22 @@ Controls.MenuItem {
property alias iconSizeMenu: iconArea.iconSize
property alias iconOverwriteColorMenu: iconArea.overwriteColor
property alias iconLayoutDirection : rowArea.layoutDirection
property alias radius: backgroundArea.radius
property var menuItemStyle : MenuItemStyle.normal
onMenuItemStyleChanged: if(!menuItemStyle) menuItemStyle = MenuItemStyle.normal
property alias textWeight : rowText.font.bold
property int offsetTopMargin : 0
property int offsetBottomMargin : 0
property bool displaySelection: true
property bool isTabBar: false
height:visible?undefined:0
Component.onCompleted: menu.width = Math.max(menu.width, implicitWidth)
Component.onCompleted: if(!isTabBar) menu.width = Math.max(menu.width, implicitWidth)
background: Rectangle {
background: Rectangle {
id: backgroundArea
color: button.down
? menuItemStyle.background.color.pressed.color
: (
@ -40,7 +44,7 @@ Controls.MenuItem {
}
contentItem:RowLayout{
id:rowArea
spacing:10
spacing: iconArea.icon? 10 : 0
Item{
Layout.fillHeight: true
Layout.preferredWidth: iconArea.icon?height/rowText.lineCount:0
@ -66,8 +70,8 @@ Controls.MenuItem {
id:rowText
Layout.fillWidth: true
Layout.fillHeight: true
Layout.leftMargin:(iconLayoutDirection == Qt.LeftToRight ? 0 : menuItemStyle.leftMargin)
Layout.rightMargin:(iconLayoutDirection == Qt.LeftToRight ? menuItemStyle.rightMargin : 0)
Layout.leftMargin:(isTabBar || iconLayoutDirection == Qt.LeftToRight ? 0 : menuItemStyle.leftMargin) + (button.checkable ? CheckBoxTextStyle.size : 0)
Layout.rightMargin:(!isTabBar && iconLayoutDirection == Qt.LeftToRight ? menuItemStyle.rightMargin : 0)
color: button.enabled
? (button.down
? menuItemStyle.text.color.pressed.color
@ -90,10 +94,55 @@ Controls.MenuItem {
verticalAlignment: Text.AlignVCenter
}
}
indicator: Rectangle {
visible: button.checkable
border.color: button.down
? CheckBoxTextStyle.color.pressed.color
: (
button.hovered
? CheckBoxTextStyle.color.hovered.color
: (
button.checked
? CheckBoxTextStyle.color.selected.color
: CheckBoxTextStyle.color.normal.color
)
)
implicitHeight: CheckBoxTextStyle.size
implicitWidth: CheckBoxTextStyle.size
radius: CheckBoxTextStyle.radius
x: button.leftPadding
y: parent.height / 2 - height / 2
Rectangle {
color: button.down
? CheckBoxTextStyle.color.pressed.color
: (button.hovered
? CheckBoxTextStyle.color.hovered.color
: (
button.checked
? CheckBoxTextStyle.color.selected.color
: CheckBoxTextStyle.color.normal.color
)
)
height: parent.height - y * 2
width: parent.width - x * 2
radius: CheckBoxTextStyle.radius
visible: button.checked
x: 4 // Fixed, no needed to use style file.
y: 4 // Same thing.
}
}
hoverEnabled: true
MouseArea{
anchors.fill:parent
visible: button.displaySelection
propagateComposedEvents:true
acceptedButtons: Qt.NoButton
cursorShape: parent.hovered

View file

@ -8,8 +8,8 @@ import ColorsList 1.0
QtObject {
property string sectionName: 'SmallButton'
property int leftPadding: 5
property int rightPadding: 5
property int leftPadding: 10
property int rightPadding: 10
property QtObject background: QtObject {
property int height: 22

View file

@ -30,37 +30,44 @@ Item {
ColumnLayout {
anchors.fill:parent
spacing: AccountStatusStyle.verticalSpacing
spacing: 0
Item{
Layout.fillHeight: true
Layout.fillWidth: true
}
RowLayout {
Layout.preferredHeight: parent.height / 2
Layout.fillHeight: false
Layout.maximumHeight: parent.height / 2
Layout.maximumWidth: parent.width
Layout.alignment: Qt.AlignBottom | Qt.AlignLeft
Layout.alignment: Qt.AlignLeft
spacing: AccountStatusStyle.horizontalSpacing
Item {
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft: Qt.AlignBottom | Qt.AlignLeft
Layout.bottomMargin: AccountStatusStyle.presenceLevel.bottomMargin
Layout.preferredHeight: AccountStatusStyle.presenceLevel.size
Layout.preferredWidth: AccountStatusStyle.presenceLevel.size
visible: !accountStatus.noAccountConfigured
Layout.preferredHeight: visible ? AccountStatusStyle.presenceLevel.size : 0
Layout.preferredWidth: visible ? AccountStatusStyle.presenceLevel.size : 0
visible: !accountStatus.noAccountConfigured && (isRegistrated || isProgressing || haveErrors)
property bool isRegistrated: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateRegistered
property bool isProgressing: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateInProgress
property bool haveErrors: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNotRegistered || AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNoProxy
PresenceLevel {
id:presenceLevel
anchors.fill:parent
level: OwnPresenceModel.presenceStatus===Presence.Offline?Presence.White:( SettingsModel.rlsUriEnabled ? OwnPresenceModel.presenceLevel : Presence.Green)
visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateRegistered
visible: parent.isRegistrated
}
BusyIndicator {
id: registrationProcessing
anchors.fill:parent
running: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateInProgress
running: parent.isProgressing
color: AccountStatusStyle.busyColor.color
}
Icon {
id: registrationError
iconSize: parent.width
icon: 'generic_error'
visible: AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNotRegistered || AccountSettingsModel.registrationState === AccountSettingsModel.RegistrationStateNoProxy
visible: parent.haveErrors
TooltipArea{
text : 'Not Registered'
}
@ -70,50 +77,47 @@ Item {
Text {
id:username
Layout.fillWidth: true
Layout.preferredHeight: accountStatus.noAccountConfigured ? -1 : parent.height / 2
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft : Qt.AlignBottom | Qt.AlignLeft
color: AccountStatusStyle.username.colorModel.color
elide: Text.ElideRight
font.bold: true
font.pointSize: AccountStatusStyle.username.pointSize
//: 'No account configured' : Status text when there is no configured account.
text: accountStatus.noAccountConfigured ? qsTr('noAccount'): AccountSettingsModel.username
verticalAlignment: Text.AlignBottom
wrapMode: Text.WordWrap
maximumLineCount: 3
}
Item {
Layout.alignment: !subtitle.visible ? Qt.AlignVCenter | Qt.AlignLeft: Qt.AlignBottom | Qt.AlignLeft
Layout.bottomMargin: 5
Layout.preferredHeight: AccountStatusStyle.presenceLevel.size
Layout.preferredWidth: AccountStatusStyle.presenceLevel.size
Layout.preferredHeight: username.height
Layout.preferredWidth: messageCounter.width
visible: !accountStatus.noAccountConfigured
MessageCounter {
id: messageCounter
anchors.fill: parent
anchors.centerIn: parent
count: CoreManager.eventCount
iconSize: AccountStatusStyle.messageCounter.iconSize
pointSize: AccountStatusStyle.messageCounter.pointSize
MouseArea{
anchors.fill: parent
onClicked: window.setView('HistoryView')
}
}
}
Item{//Spacer
Layout.fillHeight: true
Layout.fillWidth: true
}
}//RowLayout
Text {
id: subtitle
Layout.preferredHeight:parent.height / 2
Layout.fillHeight: true
Layout.maximumHeight:parent.height / 2
Layout.preferredWidth:parent.width
visible: !accountStatus.noAccountConfigured && text != username.text
color: AccountStatusStyle.sipAddress.colorModel.color
elide: Text.ElideRight
font.pointSize: AccountStatusStyle.sipAddress.pointSize
text: UtilsCpp.toDisplayString(AccountSettingsModel.sipAddress, SettingsModel.sipDisplayMode)
verticalAlignment: Text.AlignTop
}
Item{
Layout.fillHeight: true
Layout.fillWidth: true
}
}//ColumnLayout

View file

@ -80,24 +80,22 @@ function sendMessage (text) {
}
function forwardMessage(chatRoomModel, chatEntry, chatRoomConfig){
Qt.callLater(function (){// This avoid to detach virtual window while selecting chatroom/user. This can be the case when we got an address from the smartsearch bar that need to close itself before doing this stuff.
window.detachVirtualWindow()
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
flat: true,
//: 'Do you want to forward this message?' : text to confirm to forward a message
descriptionText: '<b>'+qsTr('confirmForward'),
}, function (status) {
if (status) {
if(!chatRoomModel) {
var chat = CallsListModel.createChatRoom( chatRoomConfig.subject, chatRoomConfig.haveEncryption, chatRoomConfig.participants, chatRoomConfig.toSelect)
if(chat)
chatRoomModel = chat.chatRoomModel
}
if(chatRoomModel){
chatRoomModel.forwardMessage(chatEntry)
Linphone.TimelineListModel.select(chatRoomModel)
}
window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
flat: true,
//: 'Do you want to forward this message?' : text to confirm to forward a message
descriptionText: '<b>'+qsTr('confirmForward'),
}, function (status) {
if (status) {
if(!chatRoomModel) {
var chat = Linphone.CallsListModel.createChatRoom( chatRoomConfig.subject, chatRoomConfig.haveEncryption, chatRoomConfig.participants, chatRoomConfig.toSelect)
if(chat)
chatRoomModel = chat.chatRoomModel
}
})
})
if(chatRoomModel){
chatRoomModel.forwardMessage(chatEntry)
Linphone.TimelineListModel.select(chatRoomModel)
}
window.detachVirtualWindow()
}
})
}

View file

@ -46,33 +46,45 @@ Item {
Menu {
id: messageMenu
menuStyle : MenuStyle.aux
MenuItem {
RowLayout{
id: reactionBar
property font customFont : SettingsModel.emojiFont
menuItemStyle : MenuItemStyle.aux
contentItem: RowLayout{
Layout.fillWidth: true
spacing:0
Repeater{
width: parent.width
height: 50
anchors.margins: 10 // Let parent border displayed
spacing: 0
Repeater{
model: ConstantsCpp.reactionsList
delegate: Text{
delegate: MenuItem{
isTabBar: true
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: modelData
font.family: reactionBar.customFont.family
font.pointSize: Units.dp * reactionBar.customFont.pointSize * 2
MouseArea{
Layout.fillHeight: true
Layout.topMargin: 5
Layout.bottomMargin: 5
Layout.leftMargin: 2
Layout.rightMargin: 2
radius: messageMenu.radius
down: chatMessageModel && modelData && modelData == chatMessageModel.myReaction
onTriggered: {
chatMessageModel.sendChatReaction(modelData)
messageMenu.close()
}
Text{
id: bodyItem
anchors.fill: parent
onClicked: {
chatMessageModel.sendChatReaction(modelData)
messageMenu.close()
}
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: modelData
font.family: reactionBar.customFont.family
font.pointSize: Units.dp * reactionBar.customFont.pointSize * 2
}
}
}
}
}
MenuItem {
//: 'Copy all' : Text menu to copy all message text into clipboard
text: (container.lastTextSelected == '' ? qsTr('menuCopyAll')

View file

@ -4,6 +4,7 @@ import QtQml.Models 2.15
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import Units 1.0
@ -23,6 +24,8 @@ Rectangle{
visible: reactionList.count > 0
property font customFont : SettingsModel.textMessageFont
property font customEmojiFont : SettingsModel.emojiFont
border.width: 1
border.color: ChatStyle.colorModel.color
RowLayout{
id: reactionLayout

View file

@ -19,6 +19,8 @@ Rectangle {
// entry should have these functions : presenceStatus, sipAddress, username, avatar (image)
property alias subtitleColor: description.subtitleColor
property alias subtitleIconData: description.subtitleIconData
property alias subtitleText: description.subtitleText
property alias titleColor: description.titleColor
property alias statusText : description.statusText
property alias isDarkMode: avatar.isDarkMode
@ -76,7 +78,8 @@ Rectangle {
? ''
: item.username
: item.username
isOneToOne: entry==undefined || entry.isOneToOne==undefined || entry.isOneToOne
isOneToOne: entry==undefined || (entry.isOneToOne==undefined || entry.isOneToOne) && !entry.conferenceInfoModel || false
//Component.onCompleted: console.log(username + " / " +entry + " / " +entry.conferenceInfoModel)
Icon{
anchors.top:parent.top

View file

@ -12,6 +12,7 @@ Column {
id:mainItem
property alias titleText: title.fullText
property alias subtitleText: subtitle.fullText
property QtObject subtitleIconData
property string sipAddress
property alias statusText : status.text
@ -96,38 +97,51 @@ Column {
anchors.right: parent.right
height: (parent.height-parent.topPadding-parent.bottomPadding)/parent.visibleChildren.length
visible: subtitle.fullText != '' && subtitle.fullText != title.fullText
TextEdit {
id:subtitle
property string fullText
RowLayout{
anchors.fill: parent
color: subtitleColor
font.family: SettingsModel.textMessageFont.family
font.weight: contactDescriptionStyle.subtitle.weight
font.pointSize: contactDescriptionStyle.subtitle.pointSize
textFormat: Text.RichText
horizontalAlignment: horizontalTextAlignment
verticalAlignment: (title.visible?Text.AlignTop:Text.AlignVCenter)
text: UtilsCpp.encodeTextToQmlRichFormat(subtitleMetrics.elidedText, {noLink:true})
onActiveFocusChanged: deselect();
readOnly: true
selectByMouse: true
Text{// Workaround to get implicitWidth from text without eliding
id: subtitleImplicitWidthWorkaround
text: subtitle.fullText
font.weight: subtitle.font.weight
font.pointSize: subtitle.font.pointSize
visible: false
textFormat: Text.RichText
spacing: 0
Icon {
Layout.preferredHeight: subtitleMetrics.height
Layout.preferredWidth: visible ? subtitleMetrics.height : 0
Layout.alignment: (title.visible? Qt.AlignTop : Qt.AlignVCenter)
icon: mainItem.subtitleIconData ? mainItem.subtitleIconData.icon : null
overwriteColor: mainItem.subtitleIconData ? mainItem.subtitleIconData.colorModel.color: ''
iconSize: visible ? HistoryStyle.entry.event.iconSize : 0
}
TextMetrics {
id: subtitleMetrics
font: subtitle.font
text: subtitle.fullText
elideWidth: subtitle.width
elide: Qt.ElideRight
TextEdit {
id:subtitle
property string fullText
Layout.fillWidth: true
Layout.fillHeight: true
color: subtitleColor
font.family: SettingsModel.textMessageFont.family
font.weight: contactDescriptionStyle.subtitle.weight
font.pointSize: contactDescriptionStyle.subtitle.pointSize
textFormat: Text.RichText
horizontalAlignment: horizontalTextAlignment
verticalAlignment: (title.visible?Text.AlignTop:Text.AlignVCenter)
text: UtilsCpp.encodeTextToQmlRichFormat(subtitleMetrics.elidedText, {noLink:true})
onActiveFocusChanged: deselect();
readOnly: true
selectByMouse: true
Text{// Workaround to get implicitWidth from text without eliding
id: subtitleImplicitWidthWorkaround
text: subtitle.fullText
font.weight: subtitle.font.weight
font.pointSize: subtitle.font.pointSize
visible: false
textFormat: Text.RichText
}
TextMetrics {
id: subtitleMetrics
font: subtitle.font
text: subtitle.fullText
elideWidth: subtitle.width
elide: Qt.ElideRight
}
}
}
}

View file

@ -5,6 +5,7 @@ import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
Item {
@ -17,7 +18,7 @@ Item {
implicitHeight: counterIcon.height + ContactMessageCounterStyle.verticalMargins * 2
implicitWidth: counterIcon.width + ContactMessageCounterStyle.horizontalMargins * 2
visible: count > 0 ?(entry.unreadMessagesCount !== null || entry.missedCallsCount !== null) && displayCounter:false
visible: count > 0 ?(entry.unreadMessagesCount !== null) && displayCounter:false
MessageCounter {
id: counterIcon
@ -28,10 +29,10 @@ Item {
icon: messageCounter.isComposing
? ('chat_is_composing_' + counterIcon.composingIndex)
: 'chat_count'
: ''
visible: messageCounter.count > 0 || messageCounter.isComposing
count: messageCounter.entry?Number(messageCounter.entry.unreadMessagesCount) + Number(messageCounter.entry.missedCallsCount):0
count: messageCounter.entry?Number(messageCounter.entry.unreadMessagesCount):0
Timer {
interval: 500

View file

@ -58,15 +58,15 @@ DialogPlus {
return UtilsCpp.hasCapability(entry.sipAddress, LinphoneEnums.FriendCapabilityLimeX3Dh, true)
},
handler: function (entry) {
console.debug("Call selected: " +entry + "/"+entry.sipAddress)
console.debug("Entry selected: " +entry + "/"+entry.sipAddress)
smartSearchBar.entryClicked(entry)
smartSearchBar.closeMenu()
},
}]
onEntryClicked: {
console.debug("Call selected from button: " +entry + "/"+entry.sipAddress)
console.debug("Entry selected from button: " +entry + "/"+entry.sipAddress)
mainItem.addressSelectedCallback(entry.sipAddress)
mainItem.exit(1)
}
}
Text {
@ -108,7 +108,6 @@ DialogPlus {
onEntrySelected:{
if( entry) {
mainItem.chatRoomSelectedCallback(entry.chatRoomModel)
exit(1)
}
}
}

View file

@ -7,16 +7,19 @@ import Linphone.Styles 1.0
import Utils 1.0
import UtilsCpp 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
Row {
id: mainItem
signal entryClicked(var entry)
property var _sipAddressObserver: $historyEntry.sipAddress ? SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '') : $historyEntry.title
property var sipAddressObserver: $historyEntry.sipAddress ? SipAddressesModel.getSipAddressObserver($historyEntry.sipAddress, '') : $historyEntry.title
property QtObject iconData
property string translation
Component.onDestruction: _sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
Component.onDestruction: sipAddressObserver=null// Need to set it to null because of not calling destructor if not.
Component.onCompleted: {
if ($historyEntry.status == LinphoneEnums.CallStatusSuccess) {
if(!$historyEntry.isStart){
@ -141,8 +144,8 @@ Row {
height: parent.height
text: $historyEntry && $historyEntry.title
? $historyEntry.title
: _sipAddressObserver
? ( UtilsCpp.getDisplayName(_sipAddressObserver.peerAddress || $historyEntry.sipAddress) || _sipAddressObserver)
: sipAddressObserver
? UtilsCpp.getDisplayName(sipAddressObserver.peerAddress || $historyEntry.sipAddress) || sipAddressObserver
: ''
verticalAlignment: Text.AlignVCenter
MouseArea{

View file

@ -29,13 +29,13 @@
function initView () {
history.tryToLoadMoreEntries = false
history.bindToEnd = true
history.bindToStart = true
}
function loadMoreEntries () {
if (history.atYBeginning && !history.tryToLoadMoreEntries) {
if (history.atYEnd && !history.tryToLoadMoreEntries) {
history.tryToLoadMoreEntries = true
history.positionViewAtBeginning()
history.positionViewAtEnd()
container.proxyModel.loadMoreEntries()
}
}
@ -55,11 +55,11 @@ function handleMoreEntriesLoaded (n) {
}
function handleMovementEnded () {
if (history.atYEnd) {
history.bindToEnd = true
if (history.atYBeginning) {
history.bindToStart = true
}
}
function handleMovementStarted () {
history.bindToEnd = false
history.bindToStart = false
}

View file

@ -31,7 +31,7 @@ Rectangle {
// -----------------------------------------------------------------------
property bool bindToEnd: false
property bool bindToStart: false
property bool tryToLoadMoreEntries: true
// -----------------------------------------------------------------------
@ -196,6 +196,6 @@ Rectangle {
repeat: true
running: true
onTriggered: history.bindToEnd && history.positionViewAtEnd()
onTriggered: history.bindToStart && history.positionViewAtBeginning()
}
}

View file

@ -7,7 +7,7 @@ import Linphone.Styles 1.0
Item{
id: messageCounter
property bool showOnlyNumber: false
property bool showOnlyNumber: backgroundIcon.icon == ''
property int count: 0
property alias icon: backgroundIcon.icon
property alias iconSize: amountIcon.iconSize
@ -20,15 +20,15 @@ Item{
Icon {
id: backgroundIcon
icon: 'chat_count'
iconSize: MessageCounterStyle.iconSize.message
icon: ''
iconSize: visible ? MessageCounterStyle.iconSize.message : 0
visible: !messageCounter.showOnlyNumber
}
Icon {
id: amountIcon
anchors {
horizontalCenter: parent.right
verticalCenter: parent.bottom
horizontalCenter: messageCounter.showOnlyNumber ? parent.horizontalCenter : parent.right
verticalCenter: messageCounter.showOnlyNumber ? parent.verticalCenter : parent.bottom
}
icon: 'chat_amount'
@ -39,6 +39,7 @@ Item{
anchors.centerIn: parent
color: MessageCounterStyle.text.colorModel.color
font.pointSize: messageCounter.pointSize
font.weight: Font.Bold
text: (messageCounter.count>99 ? '+' : messageCounter.count)
}
}

View file

@ -84,8 +84,7 @@ SearchBox {
searchBox.launchChat(entry.sipAddress)
searchBox.closeMenu()
},
visible: SettingsModel.standardChatEnabled,
zz: 'toto'
visible: SettingsModel.standardChatEnabled
}, {
colorSet: SettingsModel.getShowStartChatButton() ? SipAddressesViewStyle.chat : SipAddressesViewStyle.history,
secure: 1,

View file

@ -27,7 +27,7 @@ QtObject {
property int pointSize: Units.dp * 11
}
property QtObject messageCounter: QtObject {
property int bottomMargin: 4
property int size: 16
property int iconSize: 15
property int pointSize: Units.dp * 9
}
}

View file

@ -0,0 +1,34 @@
pragma Singleton
import QtQml 2.2
import Units 1.0
import ColorsList 1.0
// =============================================================================
QtObject {
property string sectionName: 'CallTimeline'
property var colorModel: ColorsList.add(sectionName+'_bg', 'd')
property QtObject backgroundColor: QtObject {
property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'timeline_header_bg')
}
property int pointSize: Units.dp * 11
property QtObject searchField: QtObject {
property var colorModel: ColorsList.add(sectionName+'_searchField', 'c')
property int pointSize: Units.dp * 9
}
property QtObject filterAction: QtObject {
property int iconSize: 30
property string name : 'filter'
property string icon : 'filter_params_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
property var foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'me_p_b_fg')
}
}

View file

@ -52,11 +52,10 @@ QtObject {
property QtObject legend: QtObject {
property QtObject backgroundColor: QtObject {
property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'f')
property var hovered: ColorsList.add(sectionName+'_legend_bg_h', 'c')
property var normal: ColorsList.add(sectionName+'_legend_bg_n', 'timeline_header_bg')
}
property var colorModel: ColorsList.add(sectionName+'_legend', 'd')
property int pointSize: Units.dp * 10
property int pointSize: Units.dp * 11
property int height: 30
property int iconSize: 28
property int leftMargin: 17
@ -97,4 +96,17 @@ QtObject {
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_n_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
}
property QtObject filterAction: QtObject {
property int iconSize: 30
property string name : 'filter'
property string icon : 'filter_params_custom'
property var backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_n', icon, 'me_n_b_bg')
property var backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_h', icon, 'me_h_b_bg')
property var backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_p', icon, 'me_p_b_bg')
property var backgroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_bg_u', icon, 'me_p_b_bg')
property var foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_n', icon, 'me_n_b_fg')
property var foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_h', icon, 'me_h_b_fg')
property var foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_p', icon, 'me_p_b_fg')
property var foregroundUpdatingColor : ColorsList.addImageColor(sectionName+'_'+name+'_fg_u', icon, 'me_p_b_fg')
}
}

View file

@ -60,6 +60,7 @@ singleton StickerStyle 1.0 Sticker/StickerStyle.qml
singleton TelKeypadStyle 1.0 TelKeypad/TelKeypadStyle.qml
singleton CallTimelineStyle 1.0 Timeline/CallTimelineStyle.qml
singleton TimelineStyle 1.0 Timeline/TimelineStyle.qml
singleton ParticipantsListViewStyle 1.0 View/ParticipantsListViewStyle.qml

View file

@ -0,0 +1,139 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import QtQuick.Shapes 1.10
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import Linphone.Styles 1.0
import ColorsList 1.0
import UtilsCpp 1.0
import 'Timeline.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
ColumnLayout{
id: mainItem
signal entrySelected(var model)
Layout.fillHeight: true
spacing: 0
// HEADER
Rectangle {
id: legendArea
Layout.preferredWidth: mainItem.width
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignTop
color: CallTimelineStyle.backgroundColor.normal.color
RowLayout{
anchors.fill: parent
spacing: 2
Text {
Layout.preferredHeight: parent.height
Layout.fillWidth: true
Layout.leftMargin: 10
color: CallTimelineStyle.colorModel.color
font.pointSize: CallTimelineStyle.pointSize
font.weight: Font.Bold
//: 'Call list' : Call histories title
text: qsTr('callListTitle')
verticalAlignment: Text.AlignVCenter
}
ActionButton {
id:filterButton
Layout.alignment: Qt.AlignRight
isCustom: true
colorSet: CallTimelineStyle.filterAction
toggled: view.model.filterFlags != 0 && view.model.filterFlags != CallHistoryProxyModel.All
onClicked: filterMenu.open()
Menu{
id: filterMenu
MenuItem{
id: incomingFilter
//: 'Incoming' : Filter label for incoming call
text: qsTr('incomingFilter')
checkable: true
}
MenuItem{
id: outgoingFilter
//: 'Outgoing' : Filter label for outgoing call
text: qsTr('outgoingFilter')
checkable: true
}
MenuItem{
id: missedFilter
//: 'Missed' : Filter label for missed call
text: qsTr('missedFilter')
checkable: true
}
}
}
}
}
// -------------------------------------------------------------------------
// Search.
// -------------------------------------------------------------------------
Rectangle{
id:searchView
Layout.preferredWidth: mainItem.width
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignCenter
color: legendArea.color
TextField {
id:searchBar
anchors.fill: parent
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.topMargin: 5
anchors.bottomMargin: 10
width: parent.width - 14
icon: text == '' ? 'search_custom' : 'close_custom'
iconSize: 30
overwriteColor: CallTimelineStyle.searchField.colorModel.color
//: 'Search in the list' : ths is a placeholder when searching something in a list
placeholderText: qsTr('searchListPlaceholderText')
onTextChanged: searchDelay.restart()
font.pointSize: CallTimelineStyle.searchField.pointSize
Timer{
id: searchDelay
interval: 600
repeat: false
onTriggered: view.model.filterText = searchBar.text
}
}
}
ScrollableListView {
id: view
Layout.fillHeight: true
Layout.preferredWidth: mainItem.width
currentIndex: -1
model: CallHistoryProxyModel{
filterFlags: (incomingFilter.checked ? CallHistoryProxyModel.Incoming : 0)
| (outgoingFilter.checked ? CallHistoryProxyModel.Outgoing : 0)
| (missedFilter.checked ? CallHistoryProxyModel.Missed : 0)
}
delegate: CallTimelineItem{
callHistoryModel: $modelData
modelIndex: index
Connections{
target: $modelData
onSelectedChanged:{
if(selected) {
view.currentIndex = index;
mainItem.entrySelected(model)
}
}
}
}
}
}

View file

@ -0,0 +1,277 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.5
import Common 1.0
import Common.Styles 1.0
import Linphone 1.0
import LinphoneEnums 1.0
import Linphone.Styles 1.0
import ColorsList 1.0
import UtilsCpp 1.0
import 'Timeline.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
Rectangle {
id: mainItem
property CallHistoryModel callHistoryModel
property bool optionsTogglable: true // Right click => display/hide options
property bool optionsToggled: false
property int modelIndex: 0
property var actions: []
height: TimelineStyle.contact.height
width: parent ? parent.width : 0
state: optionsToggled ? 'options' : 'normal'
states: [State {
name: "normal"
}, State {
name: "options"
}
]
transitions: [Transition {
from: 'normal'
to: 'options'
//NumberAnimation { target: contactView; property: 'x'; to:-contactView.width; duration: 200;}
NumberAnimation { target: optionsView; property: 'x'; to:0; duration: 200;}
},
Transition {
from: 'options'
to: 'normal'
//NumberAnimation { target: contactView; property: 'x'; to:0; duration: 200;}
NumberAnimation { target: optionsView; property: 'x'; to:optionsView.width; duration: 200;}
}
]
enabled: !contactView.showBusyIndicator
color: contactView.isSelected
? TimelineStyle.contact.backgroundColor.selected.color
: (
mainItem.modelIndex % 2 == 0
? TimelineStyle.contact.backgroundColor.a.color
: TimelineStyle.contact.backgroundColor.b.color
)
RowLayout{
anchors.fill: parent
anchors.rightMargin: 5
spacing: 0
Contact {
id: contactView
property bool isSelected: mainItem.callHistoryModel != undefined && mainItem.callHistoryModel.selected
Layout.fillHeight: true
Layout.fillWidth: true
color: isSelected
? TimelineStyle.contact.backgroundColor.selected.color
: (
mainItem.modelIndex % 2 == 0
? TimelineStyle.contact.backgroundColor.a.color
: TimelineStyle.contact.backgroundColor.b.color
)
displayUnreadMessageCount: false
entry: mainItem.callHistoryModel && (mainItem.callHistoryModel.conferenceInfoModel && mainItem.callHistoryModel
|| SipAddressesModel.getSipAddressObserver(mainItem.callHistoryModel.remoteAddress, ''))
property var subtitleSelectedColors: TimelineStyle.contact.subtitle.color.selected
property var subtitleNormalColors: TimelineStyle.contact.subtitle.color.normal
property var titleSelectedColors: TimelineStyle.contact.title.color.selected
property var titleNormalColors: TimelineStyle.contact.title.color.normal
function getIconData(){
var iconData
if(!mainItem.callHistoryModel)
return HistoryStyle.entry.event.unknownCallEvent
if (mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusSuccess) {
if(!mainItem.callHistoryModel.lastCallIsStart){
iconData = HistoryStyle.entry.event.endedCall
}else if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclined) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusMissed) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.missedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.missedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusAborted) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclined) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusEarlyAborted) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.missedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.missedIncomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusAcceptedElsewhere) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.outgoingCall
}else{
iconData = HistoryStyle.entry.event.incomingCall
}
}else if(mainItem.callHistoryModel.lastCallStatus == LinphoneEnums.CallStatusDeclinedElsewhere) {
if(mainItem.callHistoryModel.lastCallIsOutgoing ){
iconData = HistoryStyle.entry.event.declinedOutgoingCall
}else{
iconData = HistoryStyle.entry.event.declinedIncomingCall
}
}else {
iconData = HistoryStyle.entry.event.unknownCallEvent
}
return iconData
}
subtitleColor: isSelected
? subtitleSelectedColors.color
: subtitleNormalColors.color
titleColor: isSelected
? titleSelectedColors.color
: titleNormalColors.color
subtitleIconData: getIconData()
subtitleText: mainItem.callHistoryModel && UtilsCpp.toDateTimeString(mainItem.callHistoryModel.lastCallDate, 'yyyy/MM/dd - hh:mm') || ''
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
propagateComposedEvents: true
preventStealing: false
onClicked: {
if(mouse.button == Qt.LeftButton){
if(mainItem.callHistoryModel)
mainItem.callHistoryModel.selectOnly()
}else if(mainItem.optionsTogglable){
mainItem.optionsToggled = !mainItem.optionsToggled
}
}
}
}
ColumnLayout{
spacing: 0
Layout.maximumWidth: statusLayout.count > 0 || unreadMessageCounter.visible ? -1 : 0
Layout.fillHeight: true
RowLayout{
Layout.alignment: Qt.AlignTop | Qt.AlignRight
Layout.fillHeight: true
spacing: 0
ContactMessageCounter {
id: unreadMessageCounter
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: implicitWidth
Layout.preferredHeight: implicitHeight
Layout.rightMargin: 9
displayCounter: SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled
entry: contactView.entry
}
}
RowLayout{
id: statusLayout
property int count : (ephemeralIcon.visible ? 1 : 0) + (notificationsIcon.visible ? 1 : 0)
spacing: 0
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
Layout.preferredHeight: TimelineStyle.status.iconSize
visible: false //SettingsModel.standardChatEnabled || SettingsModel.secureChatEnabled
Icon{
id: notificationsIcon
Layout.preferredHeight: TimelineStyle.status.iconSize
Layout.preferredWidth: TimelineStyle.status.iconSize
icon: TimelineStyle.disabledNotifications.icon
iconSize: TimelineStyle.status.iconSize
//overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.disabledNotifications.selectedColorModel.color : TimelineStyle.disabledNotifications.colorModel.color
//visible: mainItem.timelineModel && !mainItem.timelineModel.chatRoomModel.notificationsEnabled
}
Icon{
id: ephemeralIcon
Layout.preferredHeight: TimelineStyle.status.iconSize
Layout.preferredWidth: TimelineStyle.status.iconSize
icon: TimelineStyle.ephemeralTimer.icon
iconSize: TimelineStyle.status.iconSize
//overwriteColor: mainItem.timelineModel && mainItem.timelineModel.selected ? TimelineStyle.ephemeralTimer.selectedTimerColor.color : TimelineStyle.ephemeralTimer.timerColor.color
//visible: mainItem.timelineModel && mainItem.timelineModel.chatRoomModel.ephemeralEnabled
}
}
}
}
RowLayout{
anchors.fill: parent
anchors.rightMargin: 5
visible: mainItem.actions.length > 0
Item{// Spacer
Layout.fillHeight: true
Layout.fillWidth: true
}
Repeater {
model: mainItem.actions
ActionButton {
isCustom: true
backgroundRadius: 90
colorSet: modelData.colorSet
visible: modelData.visible
onClicked: {
if( mainItem.callHistoryModel)
mainItem.actions[index].handler( // Do not use modelData on functions
mainItem.callHistoryModel
)
}
}
}
}
Item{
id: optionsView
height: mainItem.height
width: mainItem.width
x:width
visible: x!=width
RowLayout{
anchors.fill: parent
MouseArea {
Layout.fillHeight: true
Layout.fillWidth: true
onClicked: {
if(mainItem.optionsTogglable)
mainItem.optionsToggled = !mainItem.optionsToggled
}
}
Rectangle{
Layout.fillHeight: true
Layout.preferredWidth: optionsLayout.width
color: contactView.color
MouseArea {// Grabber
anchors.fill: parent
cursorShape: Qt.ArrowCursor
}
RowLayout{
id: optionsLayout
anchors.centerIn: parent
}
}
}
}
}

View file

@ -29,7 +29,7 @@ Rectangle {
property var actions: []
// ---------------------------------------------------------------------------
signal entrySelected (TimelineModel entry)
signal entrySelected (var entry)
signal showHistoryRequest()
// ---------------------------------------------------------------------------
@ -40,7 +40,6 @@ Rectangle {
anchors.fill: parent
spacing: 0
// -------------------------------------------------------------------------
Connections {
@ -56,254 +55,47 @@ Rectangle {
// -------------------------------------------------------------------------
// Legend.
// -------------------------------------------------------------------------
Rectangle {
id: legendArea
Layout.fillWidth: true
Layout.preferredHeight: TimelineStyle.legend.height
Layout.preferredWidth: timeline.width
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignTop
color: showHistory.containsMouse?TimelineStyle.legend.backgroundColor.hovered.color:TimelineStyle.legend.backgroundColor.normal.color
visible: showHistoryButton || showFiltersButtons
MouseArea{// no more showing history
id:showHistory
anchors.fill:parent
visible: showFiltersButtons
onClicked: {
timeline.showFilterView = !timeline.showFilterView
}
}
color: TimelineStyle.legend.backgroundColor.normal.color
RowLayout{
anchors.fill:parent
spacing:TimelineStyle.legend.spacing
anchors.fill: parent
Text {
Layout.preferredHeight: parent.height
Layout.fillWidth: true
Layout.leftMargin: TimelineStyle.legend.leftMargin
visible: showFiltersButtons
Layout.leftMargin: 10
color: TimelineStyle.legend.colorModel.color
font.pointSize: TimelineStyle.legend.pointSize
//: A title for filtering mode.
text: qsTr('timelineFilter')+' : '
+(timeline.model.filterFlags == 0 || timeline.model.filterFlags == TimelineProxyModel.AllChatRooms
//: 'All' The mode for timelines filtering.
? qsTr('timelineFilterAll')
//: 'Custom' The mode for timelines filtering.
: qsTr('timelineFilterCustom'))
font.weight: Font.Bold
//: 'Messages' : Title for conversations
text: qsTr('chatsTitle')
verticalAlignment: Text.AlignVCenter
}
Icon {
ActionButton {
id:filterButton
Layout.alignment: Qt.AlignRight
icon: 'filter_params_custom'
iconSize: TimelineStyle.legend.iconSize
overwriteColor: TimelineStyle.legend.colorModel.color
visible: showFiltersButtons
MouseArea{
anchors.fill:parent
onClicked:{
timeline.showFilterView = !timeline.showFilterView
isCustom: true
colorSet: TimelineStyle.filterAction
toggled: view.model.filterFlags != 0 && view.model.filterFlags != TimelineProxyModel.AllChatRooms
onClicked: filterMenu.open()
Menu{
id: filterMenu
MenuItem{
id: secureFilter
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
text: qsTr('timelineFilterSecureRooms')
checkable: true
}
MenuItem{
id: chatGroupFilter
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
text: qsTr('timelineFilterChatGroups')
checkable: true
}
}
}
MouseArea{
Layout.alignment: Qt.AlignRight
Layout.fillHeight: true
Layout.preferredWidth: TimelineStyle.legend.iconSize
visible: showFiltersButtons
onClicked:{
searchView.visible = !searchView.visible
}
Icon {
id:searchButton
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
property bool searching: searchView.visible
icon: (searchView.visible? 'close_custom': 'search_custom')
iconSize: TimelineStyle.legend.iconSize
overwriteColor: TimelineStyle.legend.colorModel.color
}
}
MouseArea{
Layout.alignment: Qt.AlignRight
Layout.rightMargin: TimelineStyle.legend.lastRightMargin
Layout.fillHeight: true
Layout.preferredWidth: TimelineStyle.legend.iconSize
visible: timeline.showHistoryButton
onClicked:{
showHistoryRequest()
}
Icon {
id:callHistoryButton
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
property bool searching: searchView.visible
icon: 'call_history_custom'
iconSize: TimelineStyle.legend.iconSize
overwriteColor: TimelineStyle.legend.colorModel.color
}
}
}
}
// -------------------------------------------------------------------------
// Filter.
// -------------------------------------------------------------------------
Rectangle{
id:exhaustiveFilterView
Layout.fillWidth: true
Layout.preferredHeight: filterChoices.height
Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.filterField.borderColor.color
border.width: 2
visible: timeline.showFilterView && !SettingsModel.useMinimalTimelineFilter
ColumnLayout{
id:filterChoices
anchors.leftMargin: 20
anchors.left:parent.left
anchors.right:parent.right
spacing:-4
function getFilterFlags(){
return secureFilter.model.get(secureFilter.currentIndex).value | groupFilter.model.get(groupFilter.currentIndex).value | ephemeralsFilter.model.get(ephemeralsFilter.currentIndex).value;
}
ComboBox {
Layout.fillWidth: true
id:secureFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'All security levels' : Filter item. Selecting it will not do any filter on security level.
key: qsTr('timelineFilterAllSecureLevelRooms'); value: 0}
ListElement {
//: 'Standard rooms' : Filter item. Selecting it will show all simple rooms.
key: qsTr('timelineFilterStandardRooms'); value: TimelineProxyModel.StandardChatRoom}
ListElement {
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
key: qsTr('timelineFilterSecureRooms'); value: TimelineProxyModel.SecureChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled && SettingsModel.standardChatEnabled
}
ComboBox {
Layout.fillWidth: true
id:groupFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'Any conversations' : Filter item. Selecting it will not do any filter on the type of conversations.
key: qsTr('timelineFilterAnyChatRooms'); value: 0}
ListElement {
//: 'Simple rooms' : Filter item. Selecting it will show all secure chat groups (with more than one participant).
key: qsTr('timelineFilterSimpleRooms'); value: TimelineProxyModel.SimpleChatRoom}
ListElement {
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
key: qsTr('timelineFilterChatGroups'); value: TimelineProxyModel.GroupChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
}
ComboBox {
Layout.fillWidth: true
id:ephemeralsFilter
currentIndex: 0
onCurrentIndexChanged: timeline.model.filterFlags = filterChoices.getFilterFlags()
textRole: "key"
model: ListModel {
ListElement {
//: 'Ephemerals on/off' : Filter item. Selecting it will not do any filter on ephemerals activation.
key: qsTr('timelineFilterAnyEphemerals'); value: 0}
ListElement {
//: 'No Ephemerals' : Filter item. Selecting it will hide all chat rooms where the ephemeral mode has been enabled.
key: qsTr('timelineFilterNoEphemerals'); value: TimelineProxyModel.NoEphemeralChatRoom}
ListElement {
//: 'Ephemerals' : Filter item. Selecting it will show all chat rooms where the ephemeral mode has been enabled.
key: qsTr('timelineFilterEphemerals'); value: TimelineProxyModel.EphemeralChatRoom}
}
haveBorder: false
haveMargin: false
backgroundColor: 'transparent'
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
}
}
}
Rectangle{
id:minimalFilterView
Layout.fillWidth: true
Layout.preferredHeight: minimalFilterChoices.height
Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.filterField.borderColor.color
border.width: 2
visible: timeline.showFilterView && SettingsModel.useMinimalTimelineFilter
ColumnLayout{
id:minimalFilterChoices
anchors.leftMargin: 20
anchors.left:parent.left
anchors.right:parent.right
spacing:-4
function getFilterFlags(){
return securedCheckBox.getValue() | groupCheckBox.getValue() | conferenceCheckBox.getValue();
}
CheckBoxText {
id: securedCheckBox
Layout.fillWidth: true
visible: SettingsModel.secureChatEnabled && SettingsModel.standardChatEnabled
//: 'Secure rooms' : Filter item. Selecting it will show all secure rooms.
text: qsTr('timelineFilterSecureRooms')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
if( checked)
return TimelineProxyModel.SecureChatRoom
else
return 0
}
}
CheckBoxText {
id: groupCheckBox
Layout.fillWidth: true
visible: SettingsModel.secureChatEnabled || SettingsModel.standardChatEnabled
//: 'Chat groups' : Filter item. Selecting it will show all chat groups (with more than one participant).
text: qsTr('timelineFilterChatGroups')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
if( checked)
return TimelineProxyModel.GroupChatRoom
else
return 0
}
}
CheckBoxText {
id: conferenceCheckBox
Layout.fillWidth: true
visible: false
//: 'Conferences' : Filter item. Selecting it will show all conferences.
text: qsTr('timelineFilterConferences')
onClicked: {
timeline.model.filterFlags = minimalFilterChoices.getFilterFlags()
}
function getValue(){
return 0
}
}
}
@ -314,25 +106,16 @@ Rectangle {
Rectangle{
id:searchView
Layout.fillWidth: true
Layout.preferredHeight: 40
Layout.preferredHeight: 50
Layout.alignment: Qt.AlignCenter
border.color: TimelineStyle.searchField.borderColor.color
border.width: 2
visible:false
onVisibleChanged: if(visible){
timeline.model.filterText = searchBar.text
searchBar.forceActiveFocus()
}else{
timeline.model.filterText = ''
}
color: legendArea.color
TextField {
id:searchBar
anchors.fill: parent
anchors.rightMargin: 7
anchors.leftMargin: 7
anchors.rightMargin: 10
anchors.leftMargin: 10
anchors.topMargin: 5
anchors.bottomMargin: 5
anchors.bottomMargin: 10
width: parent.width - 14
icon: text == '' ? 'search_custom' : 'close_custom'
iconSize: 30
@ -360,12 +143,18 @@ Rectangle {
Layout.fillHeight: true
Layout.fillWidth: true
currentIndex: -1
model: TimelineProxyModel{
listSource: TimelineProxyModel.Main
filterFlags: (secureFilter.checked ? TimelineProxyModel.SecureChatRoom : 0)
| (chatGroupFilter.checked ? TimelineProxyModel.GroupChatRoom : 0)
}
delegate: TimelineItem{
timelineModel: $modelData
modelIndex: index
optionsTogglable: timeline.optionsTogglable
actions: timeline.actions
Connections{
target: $modelData
onSelectedChanged:{

View file

@ -100,7 +100,8 @@ Rectangle {
preventStealing: false
onClicked: {
if(mouse.button == Qt.LeftButton){
mainItem.timelineModel.selected = true
if(mainItem.timelineModel)
mainItem.timelineModel.selected = true
}else if(mainItem.optionsTogglable){
mainItem.optionsToggled = !mainItem.optionsToggled
}
@ -172,9 +173,10 @@ Rectangle {
visible: modelData.visible
onClicked: {
mainItem.actions[index].handler( // Do not use modelData on functions
mainItem.timelineModel
)
if( mainItem.timelineModel)
mainItem.actions[index].handler( // Do not use modelData on functions
mainItem.timelineModel
)
}
}
@ -225,7 +227,7 @@ Rectangle {
id: deleteButton
Layout.alignment: Qt.AlignCenter
Layout.rightMargin: 6
visible: mainItem.timelineModel
isCustom: true
colorSet: contactView.isSelected ? TimelineStyle.selectedDeleteAction : TimelineStyle.deleteAction
onClicked: window.attachVirtualWindow(Utils.buildCommonDialogUri('ConfirmDialog'), {
@ -233,7 +235,8 @@ Rectangle {
descriptionText: qsTr('deleteTimeline'),
}, function (status) {
if (status) {
mainItem.timelineModel.chatRoomModel.deleteChatRoom()
if( mainItem.timelineModel)
mainItem.timelineModel.chatRoomModel.deleteChatRoom()
}
})
TooltipArea {

View file

@ -65,6 +65,8 @@ Sticker 1.0 Sticker/Sticker.qml
TelKeypad 1.0 TelKeypad/TelKeypad.qml
CallTimeline 1.0 Timeline/CallTimeline.qml
CallTimelineItem 1.0 Timeline/CallTimelineItem.qml
Timeline 1.0 Timeline/Timeline.qml
TimelineItem 1.0 Timeline/TimelineItem.qml

View file

@ -522,6 +522,12 @@ function genRandomNumber (min, max) {
return Math.random() * (max - min) + min
}
function genRandomColor(){
return '#'+ Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
+Math.floor(Math.random()*255).toString(16)
}
// -----------------------------------------------------------------------------
// Generate a random number between a set of intervals.

View file

@ -0,0 +1,43 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Clipboard 1.0
import Common 1.0
import Linphone 1.0
import Utils 1.0
import UtilsCpp 1.0
import LinphoneEnums 1.0
import App.Styles 1.0
import Common.Styles 1.0
import Linphone.Styles 1.0
import Units 1.0
import ColorsList 1.0
import 'Conversation.js' as Logic
// =============================================================================
RowLayout{
spacing: 0
CallTimeline{
Layout.fillHeight: true
Layout.preferredWidth: MainWindowStyle.menu.width
onEntrySelected:{
content.setSource('HistoryView.qml', {
callHistoryModel: model
})
}
}
Loader{
id: content
Layout.fillHeight: true
Layout.fillWidth: true
}
}

View file

@ -34,7 +34,7 @@ Item{
anchors.fill: parent
verticalAlignment: Qt.AlignVCenter
anchors.leftMargin: 40
anchors.leftMargin: 28
color: ConferencesStyle.bar.text.colorModel.color
font {
@ -44,6 +44,25 @@ Item{
//: 'Meetings' : Conference list title.
text: qsTr('conferencesTitle')
}
TextButtonB {
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 10
addHeight: 10
addWidth: 80
//: 'Create Meeting' : Button label to create a meeting
text: qsTr('createMeeting')
capitalization: Font.Capitalize
onClicked: {
window.detachVirtualWindow()
window.attachVirtualWindow(Utils.buildAppDialogUri('NewConference')
,{}, function (status) {
if( status){
setView('Conferences')
}
})
}
}
}
Rectangle {
Layout.fillWidth: true

View file

@ -9,6 +9,7 @@ import LinphoneEnums 1.0
import App.Styles 1.0
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
ColumnLayout {
@ -41,10 +42,26 @@ ColumnLayout {
rightMargin: ContactsStyle.bar.rightMargin
}
spacing: ContactsStyle.spacing
Text {
Layout.preferredHeight: parent.height
Layout.preferredWidth: contentWidth
Layout.leftMargin: 10
color: ContactsStyle.bar.foregroundColor.color
font.pointSize: ContactsStyle.bar.pointSize
font.weight: Font.Bold
font.capitalization: Font.Capitalize
text: LdapListModel.count > 0
//: 'Local contacts' : Contacts section label in main window when we have to specify that they are local to the application.
? qsTr('localContactsEntry')
//: 'Contacts' : Contacts section label in main waindow.
: qsTr('contactsEntry')
verticalAlignment: Text.AlignVCenter
}
TextField {
Layout.fillWidth: true
icon: ContactsStyle.filter.icon
iconSize: 35
overwriteColor: ContactsStyle.filter.colorModel.color
placeholderText: qsTr('searchContactPlaceholder')
@ -53,16 +70,24 @@ ColumnLayout {
ExclusiveButtons {
texts: [
//: 'All' : Filter label to display all items.
qsTr('selectAllContacts'),
qsTr('selectConnectedContacts')
//: 'Online' : Filter label to display only online contacts.
qsTr('selectOnlineContacts')
]
onClicked: contacts.useConnectedFilter = !!button
capitalization: Font.AllUppercase
onClicked: contacts.useOnlineFilter = !!button
}
Item{
Layout.fillHeight: true
Layout.fillWidth: true
}
TextButtonB {
addHeight: 15
text: qsTr('addContact')
Layout.leftMargin: 20
addHeight: 10
addWidth: 80
text: qsTr('addContact').toLowerCase()
capitalization: Font.Capitalize
onClicked: window.setView('ContactEdit')
}
}
@ -209,17 +234,26 @@ ColumnLayout {
target: lastChatRoom
onStateChanged: if(state === 1) {
console.debug("Load conversation from contacts")
window.setView('Conversation', {
chatRoomModel: lastChatRoom
})
window.setView('Conversation')
}
}
readonly property var handlers: [
CallsListModel.launchVideoCall,
CallsListModel.launchAudioCall,
function (sipAddress) {CallsListModel.launchChat( sipAddress,0 )},
function (sipAddress) {CallsListModel.launchChat( sipAddress,1 )}
function (sipAddress) {
var model = CallsListModel.launchChat( sipAddress,0 )
if(model && model.chatRoomModel) {
lastChatRoom = model.chatRoomModel
window.setView('Conversations')
}
},
function (sipAddress) {
var model = CallsListModel.launchChat( sipAddress,1 )
if(model && model.chatRoomModel) {
lastChatRoom = model.chatRoomModel
window.setView('Conversations')
}}
]
model: handlers

View file

@ -582,28 +582,13 @@ ColumnLayout {
topWidth: ConversationStyle.filters.border.topWidth
visible: chatRoomModel && (!chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
ExclusiveButtons {
id: filterButtons
anchors {
left: parent.left
leftMargin: ConversationStyle.filters.leftMargin
verticalCenter: parent.verticalCenter
}
texts: [
qsTr('displayCallsAndMessages'),
qsTr('displayCalls'),
qsTr('displayMessages')
]
onClicked: Logic.updateChatFilter(button)
}
BusyIndicator{
id: chatLoading
width: 20
height: 20
anchors.left: filterButtons.right
anchors.leftMargin: 50
anchors.left: parent.left
anchors.leftMargin: parent.width/3
anchors.verticalCenter: parent.verticalCenter
color: BusyIndicatorStyle.alternateColor.color
running: chatArea.tryingToLoadMoreEntries
@ -654,6 +639,7 @@ ColumnLayout {
}
width: parent.width-14
icon: text != '' ? 'close_custom' : 'search_custom'
iconSize: 30
overwriteColor: ConversationStyle.filters.iconColor.color
//: 'Search in messages' : this is a placeholder when searching something in the timeline list
placeholderText: qsTr('searchMessagesPlaceholder')

Some files were not shown because too many files have changed in this diff Show more