Compare commits

...

64 Commits

Author SHA1 Message Date
35482fa92f misc: implement frameless window
Several major changes to the layout have been made.
- The chat search bar is moved into the message search layout.
- The Searchbar component is stripped of unused features.
- Some remaining logic that was used to switch main loader components is removed.
- ViewCoordinator.getView gets a "force create" parameter and we no longer preload low-cost views.

NOTE: the option to use a frameless window is available within general settings

Gitlab: #1524 (Frameless Window)
Change-Id: Iec6bdf162cb0335d3ae3d9bd09dd9783991a4a57
2024-01-26 18:14:55 -05:00
788ecaa496 misc: bump daemon
Change-Id: I7a4ca97f207cff65d8853180c3437ccf6df36409
2024-01-25 14:13:56 -05:00
f40a8215d1 mainview: fix shortcuts to go to the settings page
Seems broken since a recent Qt upgrade. Calling a method in JamiQmlUtils
works as expected.

Change-Id: Ic1257a4f487560744f5ce1ea02928504ff572157
2024-01-25 10:08:36 -05:00
c6ff91bdb1 conversation: fix padding for big message
Change-Id: I45dca8960401146ca3ac09e6c7ab6e2a2d012655
2024-01-24 07:53:18 -05:00
99d415b1fe chat view: don't attempt to redefine a Loader's final property
We can't define a property called `status` for a Loader as it exists already. At best, the app will crash as it should be unable to create the chat view. At worst, this will introduce undefined behavior by confounding transfer/loader status assignments and comparisons.

Gitlab: #1537 (crash)
Change-Id: I66fb6da25cae695f7f1f520200f6eed8a2c93d03
2024-01-24 07:53:08 -05:00
4edc2d6369 messageBar: force focus when showTypo button clicked
Change-Id: Ic3980ad9ecfa66ec9767aaa1fb18376f196fd012
2024-01-22 10:18:07 -05:00
146dd21679 misc: bump daemon
Change-Id: I58fe94e1fdcf068a0cb6d20a3425d7d0098e31f3
2024-01-19 08:07:15 -05:00
fa2caa6d7c editedMessage: enable click on "edited" to open previous bodies popup
Change-Id: I45a55c57337029d3357bb1059a6d26a9656fe9b1
2024-01-19 08:04:57 -05:00
90e9a36a9e datatransfer: allow to download a cancelled file
Change-Id: If94c5e1c24d1a90f7a20f29bafc087d26782fe67
GitLab: #1523
2024-01-19 07:55:45 -05:00
95e36ef89b tests/qml: fix various issues with the MessageOptions test
This commit fixes three issues related to tst_MessageOptions.qml:
1) There was no test to check that the call to createSIPAccount() at the
   beginning of test_createMessageOptionsPopup() actually succeeded
2) The created account was not deleted at the end of the test
3) The test would occasionally crash due to an uncaught
   std::out_of_range exception thrown by the
   AccountModelPimpl::slotAccountDetailsChanged function. I've modified
   the function to issue a warning instead, which makes it consistent
   with AccountModelPimpl::slotVolatileAccountDetailsChanged and avoids
   throwing an exception from a Qt slot (which is considered undefined
   behavior according to the Qt documentation)

Change-Id: I4d939b29f27ee27de673aea7046997ef756fbcee
2024-01-18 21:21:22 -05:00
79b906f12f donation: update end date for donation campaign
Change-Id: Ib694bfb4bc194e7d6b24bf23f52949715e2efa11
2024-01-18 21:20:52 -05:00
92522d5cce AboutPopUp: update copyright years
Change-Id: Ifbb9516ce8a10b00b6ef7ec92ee38d71b48cb5a9
2024-01-18 15:43:02 -05:00
25b74cdf6e i18n: automatic bump
Change-Id: I347fec814027db3c20cc6b36e740fb2bcdead527
2024-01-18 13:40:31 -05:00
0245671855 misc: improve client app logging
- introduce a message handler
- introduce a logging category for the mainapplication object
- demo the filtering

Gitlab: #652
Change-Id: Ice1ea380bb330f576a0936e3048eb4c60a06d4e9
2024-01-16 19:48:47 -05:00
7c3eab9107 CallMessageDelegate: remove reply/react to
Change-Id: Iddeffd4e2c161ecaf0c9bdb62ed1431d78d0eac5
GitLab: #1493
2024-01-15 13:50:13 -05:00
5b6ab48037 settings panel: retrigger translation
Else, seems model is not updated correctly

Change-Id: I980a3969b72ebe0d6c702f5fc8c13779603bb8b2
GitLab: #1486
2024-01-15 13:48:39 -05:00
6003d007b8 tests/qml: add basic test for OngoingCallPage
GitLab: #1483
Change-Id: Ib8932ec76519c52547a27e29b095fc60b0e46876
2024-01-15 13:25:51 -05:00
30db1ba5f5 misc: don't prefer Vulkan RHI
WebEngine view destruction crashes on Windows 10 when using Vulkan. Disable the preference for now. It will default to D3D11.

Gitlab: #1515
Change-Id: I8396163a937b3b439569115887020d49e3a8e751
2024-01-12 10:02:25 -05:00
6aaac12758 system: implement screen saver on macOS
GitLab: #1513
Change-Id: I7f8e6a8f19ddd932d62a0523e8f95b29851567b2
2024-01-12 09:56:51 -05:00
a0fc85d0a9 call: enable screen saver after call is completed
Change-Id: Ib7bac91e802351c699c4a7e44a4c197eeca884e5
2024-01-12 09:55:51 -05:00
9c6bdec0f0 active call message: make the border continue when 2nd message
GitLab: #1509
Change-Id: Ie0d3699f86bd7f7ceffbde1b7d2bff7790919ecf
2024-01-11 08:18:33 -05:00
ce8381e817 SettingsSidePanel: select Manage account in the menu when opening the settings
GitLab: #1511

Change-Id: I05c29557683b5d5c88f74ec5916a68bf0d4c17a5
2024-01-11 08:17:53 -05:00
677ebe3297 macOS: remove QT dSYM files
This patch removes Qt dSYM files because their bundle identifiers
are not accepted by the App Store.

Change-Id: Ie999b8d273172a3810706fc78286fe0ddc81376d
2024-01-09 20:19:32 -05:00
fa67ac0462 i18n: automatic bump
Change-Id: Ie76fa55b2c62e143b6100ff99b88de7e3978c5aa
2024-01-08 16:49:04 -05:00
c0c56023cc ScrollToBottomButton: lighten DropShadow color
GitLab: #1479
Change-Id: I71f84a7089c9ad4dce8b99b340443fd2180df0d4
2024-01-08 14:45:41 -05:00
e7ee0acf3a ChatviewHeader: reduce height
Change-Id: I0c6fb3d7a8f0cf1b30fdec2a505b1ec730ef9f73
2024-01-08 14:30:36 -05:00
f1f521973b tests/qml: add test for 'About Jami' button on welcome page
GitLab: #1484
Change-Id: I4f8f577c2039ef4a2fc9e4ed731d540e26563b61
2024-01-05 12:23:40 -05:00
a4300308dc contactmodel: check if removed before adding
Change-Id: I61b3773539bf6a0774ea487e4f5aae74bd2bc635
2024-01-04 09:45:16 -05:00
815d324118 contactmodel: move profile creation on dedicated thread
This avoid a heavy I/O operation on the main pool

Change-Id: Ic5068d9d1c291b8f27ffc563933d4920af42e890
GitLab: #1450
2024-01-03 13:00:21 -05:00
2343f34b4f messaging: run previewengine on its own thread
Change-Id: Iff267600c0802fbadedb58174b5fe65bbd1a443f
2024-01-03 12:00:17 -05:00
692ba0d5a8 conversationsadapter: do not create empty profile
Change-Id: I3113b860a6a89fc4af1d228840026dc0fd078b9b
2024-01-03 09:54:49 -05:00
84150e8977 misc: bump copyright to 2024
Change-Id: I8d5f968fbedbc884c91416246049a0ef4cd652eb
2024-01-03 09:54:49 -05:00
9360458b9e misc: bump to daemon 15.0.0
Change-Id: Ifc5d5f4cb5156d75723aac58e1b34ecb5829c2b7
2024-01-03 09:54:47 -05:00
46a955aa3d misc: fix ups for conversationmodel/messagelistmodel
Removes some remaining excess complexity in the way interactions are managed by the client. Removes raw iterator access and provides thread-safe alternatives.

Change-Id: I482bf599de869245f96c4aab418127f30508ef41
2024-01-03 08:43:50 -05:00
009a3902cb emojipicker: use truthy check to avoid exception
Change-Id: I9c6acd8fe1c34d4ce5b2a172e04eea0f4a1e0148
2024-01-02 16:52:54 -05:00
32b76c8da4 messagelist: use history given from daemon (except SIP accounts)
With Jami-Daemon >= 14.0.0, the client doesn't need to construct
itself the history. This part is now handled by the daemon.
This patch uses the new API:
+ loadConversationMessages->loadConversation
+ SwarmMessageReceived/SwarmMessageUpdated/ReactionAdded/ReactionRemoved
+ remove MessageReceived
+ ConversationLoaded->SwarmLoaded

+ No need to use loadConversationUntil, the daemon will load whatever
the client needs.
+ No need to clear cache, just reset the body and emit data changes

Everything should work like before (even re-translation & changing
preview preference)

Change-Id: Iaf1fa3e84e8e157ae2d0bec210977f9a34415ebc
2024-01-02 15:22:10 -05:00
2bbd9637da packaging: add package for opensuse leap 15.5
Change-Id: I90ad05ca1bd12e041f60f42fd38bd464b5f8cb51
2024-01-02 13:27:16 -05:00
2d664eacb1 misc: fix QML tests
Moreover, add two accounts (for ChatView testing)

Change-Id: Ifb2a45002dd9e86921868257124561764e9b94c5
2024-01-02 10:31:59 -05:00
f1c90f316a PluginStoreView: add logic to improve user experience
Change-Id: Ie1e2495bed08224d6806d0df41124c4b62b7c2e0
2024-01-02 09:40:42 -05:00
5abed96b56 i18n: automatic bump
Change-Id: I82cd79eb4ee5c5e5b8eb91b507d99b67975e73e8
2024-01-01 16:42:39 -05:00
f524c39c5f contactmodel: do not save profile for account (managed by daemon)
Change-Id: I2943d91ad077892639a60117046665339e95d8fd
2023-12-28 15:21:44 -05:00
2215d51f98 disable video and photo capture when no webcam is detected
GitLab: #1470
Change-Id: I266667d1ffe53b3839dfb3327db01cfda331c71f
2023-12-28 10:04:17 -05:00
127b39bec2 recordBox: change popup placement and buttons for audio and video recording
GitLab: #1477

Change-Id: Idf18c0c4668d4e1154fc5a9d4ef674433578dded
2023-12-27 16:53:19 -05:00
43fecd1d4a i18n: automatic bump
Change-Id: I3abd6557d06c48ad0b5c9f82ddfc31a1f609a997
2023-12-27 14:11:21 -05:00
760f6dc72c Edited message: resolve display issue
GitLab: #1469
Change-Id: I4ef71f60efaea7cb90f4d83df831f566fbfbd84f
2023-12-27 14:02:55 -05:00
eaf155d8a4 PluginStoreView: ajust view to improve user experience
Gitlab: #1373
Change-Id: Ie236db62b139e0c2e9646a6338425f063bcf9456
2023-12-27 09:55:51 -05:00
3e7087e5e6 Revert "misc: fix GTK theme application on Wayland by prioritizing XCB"
This reverts commit 87aed4c039.

Reason for revert: Breaks Wayland support (without Xwayland)

Change-Id: I27a26cf784b3eea543b9cc396a130e80f295b81b
2023-12-27 08:12:13 -05:00
4ebb881be4 macOS: fix build for App Store
Change-Id: I0763138f03296de661da801e06f56083e0f92598
2023-12-25 10:57:52 -05:00
a4014b7b6f misc: fix debian version
Change-Id: I5084b5feef6b8dd9e1f3c072de0b758ca5f6c117
2023-12-22 10:21:22 -05:00
93d2201277 contactmodel: avoid crash on incorrect profile
Change-Id: I1aa09e72e7db602a489c1195ab45b897e18370bc
2023-12-22 09:54:22 -05:00
2bf414e27e misc: bump daemon
Change-Id: If3f8d438b2a3ef82b6ad9bf63cbd44d84be84498
2023-12-21 07:24:10 -05:00
c72e847bd4 Emoji Picker: correct position
GitLab: #1431

Change-Id: I5d86598da3120df5b34b375e1019bb0d0c8d88f0
2023-12-21 07:22:48 -05:00
74120737ca avatarregistry: update account before smartlist
Else, we can got some issues when switching from one account
to another

Change-Id: I9f77b7d281fc1519be6ce779efd1f908f7eae6d2
2023-12-20 16:24:57 -05:00
f2424f4968 createAccount: resolve display issue
GitLab: #1448

Change-Id: I3e0edddfa70c0a59ab01d5c1359d93b27bea0824
2023-12-20 15:55:51 -05:00
9d7eae0af8 Donation banner: change image and center
Change-Id: I8dcdcaafd4bd8e34c9cdf403236b209ee3ad56a8
2023-12-20 12:30:13 -05:00
38febbf0bc fileSending: enable click on image and video
Change-Id: I48a68504b8b738a8db59337d48a69b16f5731bbe
2023-12-20 07:51:39 -05:00
bd8938b1df TextMessageDelegate: resolve binding loop issue
Change-Id: Ia17240ba8ff20dd09ad58463e44fbcdc2156ed78
2023-12-19 12:05:57 -05:00
1e4c450423 file sending: new design
GitLab: #1325
Change-Id: Ie39a429ae53c9be3d96363fb4bd9af6b47805456
2023-12-19 09:36:14 -05:00
c1df66f28d manual Revert "Revert "app Store: disable donations""
Appstore is refusing the donations-enabled build for now.

Change-Id: I16d9cc33ed577298565a5d92e0ee247ee54865a8
2023-12-18 16:32:10 -05:00
721ea4b017 misc: bump daemon
Change-Id: I254ed23127fd781d7cffc0461d9a2cf9ba1b7b75
2023-12-18 13:45:59 -05:00
b6737f1d50 misc: fix some connect warnings when starting with 0 accounts
Change-Id: I15f3a79107912d83a3c1ffe18538c26e37a419e8
2023-12-18 11:29:52 -05:00
15eb51c7ca smartlistitemdelegate: avoid weird conversation jump
Change-Id: I951d6938b4154dccce5a267744976fdc3da7f660
2023-12-18 10:40:36 -05:00
e74be0934e linkMessage: new design
GitLab: #1325
Change-Id: Id9b4e1430575fbf53f0657e94c9a27c5b35e4a93
2023-12-15 09:09:55 -05:00
a4b758611c deletedMessage: new design
GitLab: #1325
Change-Id: I3bca1e25e9e66ffa86670bb5194812fb6d78ce8a
2023-12-15 09:03:55 -05:00
671 changed files with 58881 additions and 56075 deletions

View File

@ -1,4 +1,4 @@
# Copyright (C) 2020-2023 Savoir-faire Linux Inc.
# Copyright (C) 2020-2024 Savoir-faire Linux Inc.
#
# Author: Albert Babí <albert.babi@savoirfairelinux.com>
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
@ -21,7 +21,7 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required(VERSION 3.19)
if(APPLE)
project(Jami)
@ -75,6 +75,37 @@ if(NOT MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "-Og -ggdb")
endif()
include(${PROJECT_SOURCE_DIR}/extras/build/cmake/contrib_tools.cmake)
set(EXTRA_PATCHES_DIR ${PROJECT_SOURCE_DIR}/extras/patches)
list(APPEND QWINDOWKIT_OPTIONS
QWINDOWKIT_BUILD_WIDGETS OFF
QWINDOWKIT_INSTALL OFF
QWINDOWKIT_BUILD_STATIC ON
)
if(WIN32)
list(APPEND QWINDOWKIT_PATCHES ${EXTRA_PATCHES_DIR}/0002-workaround-right-margin.patch)
list(APPEND QWINDOWKIT_OPTIONS QWINDOWKIT_ENABLE_WINDOWS_SYSTEM_BORDERS OFF)
endif()
# qmsetup uses the wrong package dir on Fedora at least.
check_redhat_based(IS_REDHAT_BASED)
if(IS_REDHAT_BASED)
list(APPEND QWINDOWKIT_PATCHES ${EXTRA_PATCHES_DIR}/0001-fix-fedora-fc-build.patch)
set(qmsetup_cmake_path ${CMAKE_BINARY_DIR}/_install/lib64/cmake/qmsetup)
endif()
# qwindowkit (frameless window)
add_fetch_content(
TARGET qwindowkit
URL https://github.com/stdware/qwindowkit.git
BRANCH 79b1f3110754f9c21af2d7dacbd07b1a9dbaf6ef
PATCHES ${QWINDOWKIT_PATCHES}
OPTIONS ${QWINDOWKIT_OPTIONS}
)
list(APPEND CLIENT_INCLUDE_DIRS ${QWindowKit_BINARY_DIR}/include)
list(APPEND CLIENT_LIBS QWindowKit::Quick)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
@ -102,7 +133,7 @@ if(QT6_VER AND QT6_PATH)
find_package(QT NAMES Qt6 REQUIRED
PATHS ${QT6_PATH} NO_DEFAULT_PATH)
else()
message(STATUS "Looking for Qt 6" ${CMAKE_PREFIX_PATH})
message(STATUS "Looking for Qt 6 in ${CMAKE_PREFIX_PATH}")
find_package(QT NAMES Qt6 REQUIRED)
endif()
if (${QT_VERSION_MINOR} GREATER_EQUAL ${QT6_MINVER_MINOR})
@ -343,6 +374,8 @@ if(Vulkan_FOUND)
add_definitions(-DHAS_VULKAN)
include_directories(${Vulkan_INCLUDE_DIR})
endif()
# Define PREFER_VULKAN to prefer Vulkan over the default API
# on GNU/Linux and Windows. Metal is always preferred on macOS.
if(MSVC)
set(WINDOWS_SYS_LIBS
@ -798,6 +831,7 @@ else()
MACOSX_BUNDLE_COPYRIGHT "${PROJ_COPYRIGHT}")
if(APPSTORE)
message(STATUS "app store version")
add_definitions(-DAPPSTORE)
set_target_properties(${PROJECT_NAME} PROPERTIES
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/appstore/Jami.entitlements")
else()

View File

@ -38,7 +38,7 @@ cf [INSTALL.md](/INSTALL.md)
# License
Copyright (C) 2020-2023 Savoir-faire Linux Inc.
Copyright (C) 2020-2024 Savoir-faire Linux Inc.
Jami 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.

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# build.py --- Convenience script for building and running Jami
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# 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

2
daemon

Submodule daemon updated: 71841b525d...205904ed4d

View File

@ -1,7 +1,7 @@
# Taken from:
# https://cmake.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
#
# Copyright (C) 2021-2023 Savoir-faire Linux Inc.
# Copyright (C) 2021-2024 Savoir-faire Linux Inc.
#
# 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

View File

@ -0,0 +1,84 @@
# Copyright (C) 2024 Savoir-faire Linux Inc.
#
# 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
include(FetchContent)
include(CMakeParseArguments)
# Helper function to check if the current distribution is Red Hat-based
function(check_redhat_based IS_REDHAT_BASED)
set(${IS_REDHAT_BASED} FALSE PARENT_SCOPE)
# Check for the existence of /etc/os-release
if(EXISTS "/etc/os-release")
# Read the content of the file
file(READ "/etc/os-release" OS_RELEASE_CONTENT)
# Check if the distribution is Fedora or Red Hat-based
string(REGEX MATCH "ID=fedora|ID_LIKE=\"rhel fedora\"" MATCH_RESULT "${OS_RELEASE_CONTENT}")
if(MATCH_RESULT)
set(${IS_REDHAT_BASED} TRUE PARENT_SCOPE)
message(STATUS "Running on a Red Hat-based distribution (Fedora, RHEL, CentOS, etc.)")
else()
message(STATUS "Not a Red Hat-based distribution")
endif()
else()
message(STATUS "Cannot determine the distribution type: /etc/os-release not found")
endif()
endfunction()
# Helper function to add external content with patches and options.
# Parameters:
# TARGET: Name of the target to create
# URL: URL of the git repository
# BRANCH: Branch to checkout
# PATCHES: List of patch files to apply
# OPTIONS: List of options to set prior to calling FetchContent_MakeAvailable
function(add_fetch_content)
# Parse function arguments
set(oneValueArgs TARGET URL BRANCH)
set(multiValueArgs PATCHES OPTIONS)
cmake_parse_arguments(PARSE_ARGV 0 AFCWP "" "${oneValueArgs}" "${multiValueArgs}")
# Create a string for the patch command
set(patch_cmd "")
# If patches is not empty, start the command with "git apply"
if(NOT "${AFCWP_PATCHES}" STREQUAL "")
set(patch_cmd git apply)
endif()
foreach(patch_file IN LISTS AFCWP_PATCHES)
list(APPEND patch_cmd "${patch_file}")
endforeach()
# Declare the external content
FetchContent_Declare(
${AFCWP_TARGET}
GIT_REPOSITORY ${AFCWP_URL}
GIT_TAG ${AFCWP_BRANCH}
PATCH_COMMAND ${patch_cmd}
UPDATE_DISCONNECTED 1
)
# Apply options
list(LENGTH AFCWP_OPTIONS options_length)
math(EXPR max_idx "${options_length} - 1")
foreach(idx RANGE 0 ${max_idx} 2)
list(GET AFCWP_OPTIONS ${idx} key)
math(EXPR value_idx "${idx} + 1")
list(GET AFCWP_OPTIONS ${value_idx} value)
set(${key} ${value} CACHE STRING "${key}" FORCE)
endforeach()
# Make the content available
FetchContent_MakeAvailable(${AFCWP_TARGET})
endfunction()

View File

@ -1,4 +1,4 @@
# Copyright (C) 2015-2023 Savoir-faire Linux Inc.
# Copyright (C) 2015-2024 Savoir-faire Linux Inc.
#
# Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
# Author: Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com>

View File

@ -66,4 +66,9 @@ RUN apt-get install -y -o Acquire::Retries=10 \
libssl-dev
RUN apt-get install -y pandoc \
googletest \
libgtest-dev
libgtest-dev \
wget
# Install a recent version of CMake
ADD extras/packaging/gnu-linux/scripts/install-cmake.sh /opt/install-cmake.sh
RUN /opt/install-cmake.sh

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (C) 2015-2023 Savoir-faire Linux Inc. -->
<!-- Copyright (C) 2015-2024 Savoir-faire Linux Inc. -->
<component type="desktop-application">
<id>net.jami.Jami</id>
<metadata_license>CC-BY-SA-3.0</metadata_license>

View File

@ -1,4 +1,4 @@
// Copyright (C) 2021-2023 Savoir-faire Linux Inc.
// Copyright (C) 2021-2024 Savoir-faire Linux Inc.
//
// Author: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
//

View File

@ -1,5 +1,5 @@
# -*- mode: makefile; -*-
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# Author: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
#
@ -49,7 +49,7 @@ QT_MAJOR := 6
QT_MINOR := 5
QT_PATCH := 3
QT_TARBALL_CHECKSUM := 7cda4d119aad27a3887329cfc285f2aba5da85601212bcb0aea27bd6b7b544cb
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-0
DEBIAN_QT_VERSION := $(QT_MAJOR).$(QT_MINOR).$(QT_PATCH)-1
DEBIAN_QT_DSC_FILENAME := libqt-jami_$(DEBIAN_QT_VERSION).dsc
QT_JAMI_PREFIX := /usr/lib/libqt-jami
@ -173,6 +173,7 @@ DISTRIBUTIONS := \
fedora_39 \
alma_9 \
opensuse-leap_15.4 \
opensuse-leap_15.5 \
snap
IS_SHELL_INTERACTIVE := $(shell [ -t 0 ] && echo yes)

View File

@ -0,0 +1,111 @@
FROM opensuse/leap:15.5
RUN zypper refresh
RUN zypper --non-interactive install -y \
dnf \
dnf-command\(builddep\) \
rpmdevtools \
Mesa-dri-devel Mesa-dri \
git \
gcc10 \
gcc10-c++ \
rpm-build \
tar \
make \
autoconf \
automake \
nasm \
speexdsp-devel \
libpulse-devel \
libcanberra-devel \
libcurl-devel \
libtool \
pcre-devel \
yaml-cpp-devel \
libXext-devel \
libXfixes-devel \
yasm \
speex-devel \
libgsm-devel \
chrpath \
check \
astyle \
gettext-devel \
which \
alsa-lib-devel \
systemd-devel \
libuuid-devel \
uuid-devel \
libopus-devel \
patch \
jsoncpp-devel \
webkit2gtk3-devel \
libcryptopp-devel \
libva-devel \
libvdpau-devel \
msgpack-c-devel \
msgpack-cxx-devel \
clutter-devel \
openssl-devel \
clutter-gtk-devel \
libnma-devel \
libcryptopp-devel \
libexpat-devel \
gnome-icon-theme-symbolic \
libgsm-devel \
gtk3-devel \
libappindicator-devel \
sqlite-devel \
ffmpeg-4-libavutil-devel \
gtk3-devel\
qrencode-devel \
python3-python-dateutil \
python3-html5lib \
libsndfile-devel \
libdrm \
gperf \
bison \
flex \
ffmpeg ffmpeg-devel \
nodejs20 \
mozilla-nss-devel \
python-xml \
python3-six \
python3-importlib-metadata \
libxcb* \
libxkb* \
libX11-devel \
libXrender-devel \
libfreetype6 \
xcb-util-image-devel \
xcb-util-keysyms-devel \
xcb-util-renderutil-devel \
xcb-util-wm-devel \
xorg-x11-devel \
xz \
xkeyboard-config \
libnotify \
argon2-devel \
libxshmfence-devel \
xproto-devel \
xcb-proto-devel \
xcb-* \
xorg-* \
vulkan-devel \
ninja \
gstreamer-devel \
gstreamer-plugins-good \
gstreamer-plugins-bad-devel \
gstreamer-plugins-base-devel \
cmake \
wget
RUN update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 50
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 50
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
ENV CC=gcc
ENV CXX=g++
CMD ["/opt/build-package-rpm.sh"]

View File

@ -1,5 +1,5 @@
#!/bin/sh
# Copyright (C) 2021-2023 Savoir-faire Linux Inc.
# Copyright (C) 2021-2024 Savoir-faire Linux Inc.
#
# Author: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
#

View File

@ -1,4 +1,4 @@
;;; Copyright (C) 2021-2023 Savoir-faire Linux Inc.
;;; Copyright (C) 2021-2024 Savoir-faire Linux Inc.
;;;
;;; Author: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>
;;;

View File

@ -3,7 +3,7 @@ Upstream-Name: jami
Upstream-Contact: Amin Bandali <bandali@gnu.org>
Source: https://dl.jami.net/release/tarballs/
Files: *
Copyright: 2004-2023 Savoir-faire Linux Inc.
Copyright: 2004-2024 Savoir-faire Linux Inc.
License: GPL-3+
Comment: Upstream embeds everything that is needed to build Jami inside the release tarball.
Everything that is already in Debian has been removed.
@ -50,7 +50,7 @@ Files: daemon/src/media/audio/opensl/audio_common.h
daemon/src/media/audio/opensl/audio_recorder.h
daemon/src/media/audio/opensl/buf_manager.h
Copyright: 2015 The Android Open Source Project
2015-2023 Savoir-faire Linux Inc.
2015-2024 Savoir-faire Linux Inc.
License: Apache-2.0
Files: daemon/extras/tools/bootstrap

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019-2023 Savoir-faire Linux Inc.
# Copyright (C) 2019-2024 Savoir-faire Linux Inc.
#
# Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com>
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com>
# Author: Maxim Cournoyer <maxim.cournoyer@savoirfairelinux.com>

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Copyright (C) 2020-2023 Savoir-faire Linux Inc.
# Copyright (C) 2020-2024 Savoir-faire Linux Inc.
#
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
#

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# Author: Alexandre Viau <alexandre.viau@savoirfairelinux.com>
# Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Copyright (C) 2021-2023 Savoir-faire Linux Inc.
# Copyright (C) 2021-2024 Savoir-faire Linux Inc.
#
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
#

View File

@ -1,6 +1,6 @@
#!/bin/sh
#
# Copyright (C) 2023 Savoir-faire Linux Inc.
# Copyright (C) 2024 Savoir-faire Linux Inc.
#
# Author: Amin Bandali <amin.bandali@savoirfairelinux.com>
#

View File

@ -0,0 +1,25 @@
From 161d28abb6784115ad71fcb6977e112e9d5756d4 Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Tue, 23 Jan 2024 15:38:34 -0500
Subject: [PATCH] fix-fedora-fc-build
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0fb89c8..3a6ad6d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -65,7 +65,7 @@ if(NOT TARGET qmsetup::library)
)
# Find package again
- find_package(qmsetup REQUIRED PATHS ${_package_path})
+ find_package(qmsetup REQUIRED PATHS ${_package_path} ${qmsetup_cmake_path})
# Update import path
set(qmsetup_DIR ${_package_path} CACHE PATH "" FORCE)
--
2.34.1

View File

@ -0,0 +1,34 @@
From ca2be6466c150d1b82a646d97b27df35b45d90f1 Mon Sep 17 00:00:00 2001
From: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
Date: Tue, 9 Jan 2024 15:25:19 -0500
Subject: [PATCH] workaround right margin
---
src/core/contexts/win32windowcontext.cpp | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/core/contexts/win32windowcontext.cpp b/src/core/contexts/win32windowcontext.cpp
index 3f6623e..9ee7752 100644
--- a/src/core/contexts/win32windowcontext.cpp
+++ b/src/core/contexts/win32windowcontext.cpp
@@ -402,6 +402,17 @@ namespace QWK {
return true;
}
}
+
+#if !QWINDOWKIT_CONFIG(ENABLE_WINDOWS_SYSTEM_BORDERS)
+ if (msg->message == WM_MOVE || msg->message == WM_SIZE ||
+ (msg->message == WM_IME_SETCONTEXT && (GetForegroundWindow() == msg->hwnd))) {
+ static const auto flags = SWP_FRAMECHANGED | SWP_NOMOVE |
+ SWP_NOSIZE | SWP_NOZORDER |
+ SWP_NOOWNERZORDER;
+ SetWindowPos(msg->hwnd, NULL, 0, 0, 0, 0, flags);
+ }
+#endif
+
return false;
}
--
2.7.4

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2022-2023 Savoir-faire Linux Inc.
# Copyright (C) 2022-2024 Savoir-faire Linux Inc.
#
# 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

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (C) 2021-2023 Savoir-faire Linux Inc.
# Copyright (C) 2021-2024 Savoir-faire Linux Inc.
#
# 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

View File

@ -1,4 +1,4 @@
# Copyright (C) 2019-2023 Savoir-faire Linux Inc.
# Copyright (C) 2019-2024 Savoir-faire Linux Inc.
#
# 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

View File

@ -1,7 +1,7 @@
#!/usr/bin/env bash
# install.sh --- build and install Jami daemon and client
# Copyright (C) 2016-2023 Savoir-faire Linux Inc.
# Copyright (C) 2016-2024 Savoir-faire Linux Inc.
#
# 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

View File

@ -20,6 +20,8 @@ rm -rf Jami.app/Contents/Frameworks/QtWebEngineQuickDelegatesQml.framework
rm -rf Jami.app/Contents/Frameworks/QtWebEngineQuick.framework
rm -rf Jami.app/Contents/Frameworks/QtWebEngineCore.framework
rm -rf Jami.app/Contents/Frameworks/QtWebChannel.framework
echo "remove web dSYM files"
find Jami.app/Contents/Resources/qml -type d -name "*.dSYM" -exec rm -r {} \;
codesign --force --sign "${APP_CERTIFICATE}" --entitlements ../resources/entitlements/appstore/Jami.entitlements Jami.app
codesign --verify Jami.app
echo "create .pkg"

View File

@ -1,7 +1,7 @@
#!/usr/bin/python
##
## Copyright (C) 2016-2023 Savoir-faire Linux Inc.
## Copyright (C) 2016-2024 Savoir-faire Linux Inc.
##
## Author: Edric Milaret <edric.ladent-milaret@savoirfairelinux.com>
## Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>

View File

@ -1,15 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="43" height="52.655" viewBox="0 0 43 52.655">
<defs>
<clipPath id="clip-path">
<rect id="Rectangle_268" data-name="Rectangle 268" width="38" height="24" transform="translate(-0.407 0.083)" fill="#fff" stroke="#707070" stroke-width="1"/>
</clipPath>
</defs>
<g id="Icon_Donate" transform="translate(-22 -189.345)">
<rect id="Rectangle_267" data-name="Rectangle 267" width="43" height="10" rx="5" transform="translate(22 232)" fill="#9eb3c3"/>
<path id="Path_459" data-name="Path 459" d="M9.674,17.083,8.562,16.07C4.609,12.486,2,10.122,2,7.221A4.18,4.18,0,0,1,6.221,3,4.6,4.6,0,0,1,9.674,4.6,4.6,4.6,0,0,1,13.128,3a4.18,4.18,0,0,1,4.221,4.221c0,2.9-2.609,5.265-6.562,8.856Z" transform="translate(22.407 199.828)" fill="#ff0045" opacity="0.3"/>
<path id="Path_460" data-name="Path 460" d="M6.953,12.088l-.718-.654C3.684,9.122,2,7.6,2,5.724A2.7,2.7,0,0,1,4.724,3,2.966,2.966,0,0,1,6.953,4.035,2.966,2.966,0,0,1,9.182,3a2.7,2.7,0,0,1,2.724,2.724c0,1.872-1.684,3.4-4.235,5.716Z" transform="translate(45.571 186.345)" fill="#ff0045" opacity="0.16"/>
<g id="Mask_Group_38" data-name="Mask Group 38" transform="translate(24.407 213.918)" clip-path="url(#clip-path)">
<path id="Path_270" data-name="Path 270" d="M12.649,22.542l-1.544-1.406C5.621,16.163,2,12.883,2,8.857A5.8,5.8,0,0,1,7.857,3a6.377,6.377,0,0,1,4.792,2.226A6.377,6.377,0,0,1,17.442,3,5.8,5.8,0,0,1,23.3,8.857c0,4.025-3.621,7.306-9.105,12.289Z" transform="translate(5.992 5.54)" fill="#ff0045"/>
</g>
</g>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 43 52.7" style="enable-background:new 0 0 43 52.7;" xml:space="preserve">
<style type="text/css">
.st0{fill:#9EB3C3;}
.st1{opacity:0.3;fill:#FF0045;enable-background:new ;}
.st2{opacity:0.16;fill:#FF0045;enable-background:new ;}
.st3{fill:#FF0045;}
</style>
<g id="Icon_Donate" transform="translate(-22 -189.345)">
<path id="Rectangle_267" class="st0" d="M27,232h33c2.8,0,5,2.2,5,5l0,0c0,2.8-2.2,5-5,5H27c-2.8,0-5-2.2-5-5l0,0
C22,234.2,24.2,232,27,232z"/>
<path id="Path_459" class="st1" d="M32.1,216.9l-1.1-1c-4-3.6-6.6-5.9-6.6-8.8c0-2.3,1.8-4.2,4.1-4.2c0,0,0.1,0,0.1,0
c1.3,0,2.6,0.6,3.5,1.6c0.9-1,2.1-1.6,3.5-1.6c2.3,0,4.2,1.8,4.2,4.1c0,0,0,0.1,0,0.1c0,2.9-2.6,5.3-6.6,8.9L32.1,216.9z"/>
<path id="Path_460" class="st2" d="M52.5,198.4l-0.7-0.7c-2.6-2.3-4.2-3.8-4.2-5.7c0-1.5,1.2-2.7,2.7-2.7c0,0,0,0,0,0
c0.9,0,1.7,0.4,2.2,1c0.6-0.7,1.4-1,2.2-1c1.5,0,2.7,1.2,2.7,2.7c0,0,0,0,0,0c0,1.9-1.7,3.4-4.2,5.7L52.5,198.4z"/>
<path class="st3" d="M37.3,236.7h11.4c3.1-3,4.9-5.5,4.9-8.4c0,0,0-0.1,0-0.1c0-3.2-2.7-5.8-5.9-5.7c-1.8,0-3.6,0.8-4.8,2.2
c-1.2-1.4-2.9-2.2-4.8-2.2c0,0-0.1,0-0.1,0c-3.2,0-5.8,2.7-5.7,5.9C32.4,231.2,34.3,233.7,37.3,236.7z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,15 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10.88" height="10.88"
viewBox="0 0 10.88 10.88">
<defs>
<style>
.cls-1 {
fill: none;
stroke: white;
stroke-miterlimit: 10;
stroke-width: 1.25px;
}
</style>
</defs>
<line class="cls-1" x1="0.44" y1="0.44" x2="10.44" y2="10.44" />
<line class="cls-1" x1="0.44" y1="10.44" x2="10.44" y2="0.44" />
</svg>

After

Width:  |  Height:  |  Size: 444 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1594017175519"
class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1933"
xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16">
<defs>
<style type="text/css"></style>
</defs>
<path
d="M874.666667 128h-170.666667a21.333333 21.333333 0 0 0 0 42.666667h119.168l-176.917333 176.917333a21.333333 21.333333 0 1 0 30.165333 30.165333L853.333333 200.832V320a21.333333 21.333333 0 0 0 42.666667 0V149.333333a21.333333 21.333333 0 0 0-21.333333-21.333333zM347.584 646.250667L170.666667 823.168V704a21.333333 21.333333 0 0 0-42.666667 0v170.666667a21.333333 21.333333 0 0 0 21.333333 21.333333h170.666667a21.333333 21.333333 0 0 0 0-42.666667H200.832l176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333-30.165333zM874.666667 682.666667a21.333333 21.333333 0 0 0-21.333334 21.333333v119.168l-176.917333-176.917333a21.333333 21.333333 0 0 0-30.165333 30.165333L823.168 853.333333H704a21.333333 21.333333 0 0 0 0 42.666667h170.666667a21.333333 21.333333 0 0 0 21.333333-21.333333v-170.666667a21.333333 21.333333 0 0 0-21.333333-21.333333zM200.832 170.666667H320a21.333333 21.333333 0 0 0 0-42.666667H149.333333a21.333333 21.333333 0 0 0-21.333333 21.333333v170.666667a21.333333 21.333333 0 0 0 42.666667 0V200.832l176.917333 176.917333a21.333333 21.333333 0 0 0 30.165333-30.165333z"
fill="#ffffff" p-id="1934"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,12 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="10" height="10" viewBox="0 0 10 10">
<defs>
<style>
.cls-1 {
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
</style>
</defs>
<rect class="cls-1" x="0.5" y="0.5" width="9" height="9" />
</svg>

After

Width:  |  Height:  |  Size: 328 B

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" viewBox="0 0 10 10" style="enable-background:new 0 0 10 10;" xml:space="preserve">
<style type="text/css">
.st0 {
fill: white;
}
</style>
<rect y="4.5" class="st0" width="10" height="1" />
</svg>

After

Width:  |  Height:  |  Size: 467 B

View File

@ -0,0 +1,16 @@
<svg id="图层_1" data-name="图层 1" xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 12 12">
<defs>
<style>
.cls-1 {
fill: none;
stroke: white;
stroke-miterlimit: 10;
}
</style>
</defs>
<rect class="cls-1" x="0.5" y="2.5" width="9" height="9" />
<line class="cls-1" x1="2.5" y1="2.5" x2="2.5" y2="0.5" />
<line class="cls-1" x1="12" y1="0.5" x2="2" y2="0.5" />
<line class="cls-1" x1="11.5" y1="10" x2="11.5" />
<line class="cls-1" x1="10" y1="9.5" x2="12" y2="9.5" />
</svg>

After

Width:  |  Height:  |  Size: 559 B

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -73,17 +73,26 @@ QtObject {
function saveWindowSettings() {
// If closed-to-tray or minimized or fullscreen, save the cached windowedVisibility
// value instead.
if (isHidden || isFullScreen) {
AppSettingsManager.setValue(Settings.WindowState, priv.windowedVisibility)
} else {
AppSettingsManager.setValue(Settings.WindowState, visibility)
}
const visibilityToSave = isHidden || isFullScreen ? priv.windowedVisibility : visibility;
// Likewise, don't save fullscreen geometry.
const geometry = isFullScreen ?
priv.windowedGeometry :
Qt.rect(appWindow.x, appWindow.y,
appWindow.width, appWindow.height)
appWindow.width, appWindow.height);
// QWK: Account for the frameless window's offset.
if (appWindow.useFrameless) {
if (Qt.platform.os.toString() !== "osx") {
// Add [7, 30, 0, 0] on Windows and GNU/Linux.
geometry.x += 7;
geometry.y += 30;
}
}
console.debug("Saving window: " + JSON.stringify(geometry) + " " + visibilityToSave);
AppSettingsManager.setValue(Settings.WindowState, visibilityToSave)
AppSettingsManager.setValue(Settings.WindowGeometry, geometry)
}
@ -111,6 +120,8 @@ QtObject {
const visibilityStr = AppSettingsManager.getValue(Settings.WindowState)
var visibilitySetting = parseInt(visibilityStr)
console.debug("Restoring window: " + JSON.stringify(geometry) + " " + visibilitySetting)
// We should never restore a hidden or fullscreen state here. Default to normal
// windowed state in such a case. This shouldn't happen.
if (visibilitySetting === Window.Hidden || visibilitySetting === Window.FullScreen) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Albert Babí <albert.babi@savoirfairelinux.com>
@ -24,29 +24,30 @@ import QtQuick.Window
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Enums 1.1
import net.jami.Helpers 1.1
import net.jami.Constants 1.1
import "mainview"
import "mainview/components"
import "wizardview"
import "commoncomponents"
import QWindowKit
ApplicationWindow {
id: root
id: appWindow
property bool isRTL: UtilsAdapter.isRTL
LayoutMirroring.enabled: isRTL
LayoutMirroring.childrenInherit: isRTL
enum LoadedSource {
MainView,
AccountMigrationView,
None
}
// This needs to be set from the start.
readonly property bool useFrameless: UtilsAdapter.getAppValue(Settings.Key.UseFramelessWindow)
onActiveFocusItemChanged: {
focusOverlay.margin = -5;
@ -70,7 +71,7 @@ ApplicationWindow {
sourceComponent: GenericErrorsRow {
id: genericError
text: CurrentAccount.enabled ? JamiStrings.noNetworkConnectivity : JamiStrings.disabledAccount
height: visible? JamiTheme.chatViewHeaderPreferredHeight : 0
height: visible? JamiTheme.qwkTitleBarHeight : 0
}
}
@ -88,37 +89,31 @@ ApplicationWindow {
border.color: JamiTheme.tintedBlue
}
property ApplicationWindow appWindow: root
property LayoutManager layoutManager: LayoutManager {
appContainer: appContainer
}
property ViewManager viewManager: ViewManager {
}
property ViewCoordinator viewCoordinator: ViewCoordinator {
viewManager: root.viewManager
// Used to manage full screen mode and save/restore window geometry.
LayoutManager {
id: layoutManager
appContainer: fullscreenContainer
}
// Used to manage dynamic view loading and unloading.
ViewManager {
id: viewManager
}
// Used to manage the view stack and the current view.
ViewCoordinator {
id: viewCoordinator
}
// Used to prevent the window from being visible until the
// window geometry has been restored and the view stack has
// been loaded.
property bool windowSettingsLoaded: false
// This setting can be used to block a loading Jami instance
// from showNormal() and showMaximized() when starting minimized.
property bool allowVisibleWindow: true
function checkLoadedSource() {
var sourceString = mainApplicationLoader.source.toString();
if (sourceString === JamiQmlUtils.mainViewLoadPath)
return MainApplicationWindow.LoadedSource.MainView;
return MainApplicationWindow.LoadedSource.None;
}
function startClient() {
setMainLoaderSource(JamiQmlUtils.mainViewLoadPath);
}
function setMainLoaderSource(source) {
if (checkLoadedSource() === MainApplicationWindow.LoadedSource.MainView) {
cleanupMainView();
}
mainApplicationLoader.setSource(source);
}
function cleanupMainView() {
// Save the main view window size if loading anything else.
layoutManager.saveWindowSettings();
@ -139,88 +134,148 @@ ApplicationWindow {
title: JamiStrings.appTitle
visible: mainApplicationLoader.status === Loader.Ready && windowSettingsLoaded && allowVisibleWindow
visible: mainViewLoader.status === Loader.Ready && windowSettingsLoaded && allowVisibleWindow
// To facilitate reparenting of the callview during
// fullscreen mode, we need QQuickItem based object.
Item {
id: appContainer
Connections {
id: connectionMigrationEnded
anchors.fill: parent
target: CurrentAccountToMigrate
function onAccountNeedsMigration(accountId) {
viewCoordinator.present("AccountMigrationView");
}
function onAllMigrationsFinished() {
viewCoordinator.dismiss("AccountMigrationView");
viewCoordinator.present("WelcomePage");
}
}
function initMainView(view) {
console.info("Initializing main view");
// Main window, load any valid app settings, and allow the
// layoutManager to handle as much as possible.
layoutManager.restoreWindowSettings();
// QWK: setup
if (useFrameless) {
windowAgent.setTitleBar(titleBar);
// Now register the system buttons (non-macOS).
if (sysBtnsLoader.item) {
const sysBtns = sysBtnsLoader.item;
windowAgent.setSystemButton(WindowAgent.Minimize, sysBtns.minButton);
windowAgent.setSystemButton(WindowAgent.Maximize, sysBtns.maxButton);
windowAgent.setSystemButton(WindowAgent.Close, sysBtns.closeButton);
}
}
// Set the viewCoordinator's root item.
viewCoordinator.init(view);
// Navigate to something.
if (UtilsAdapter.getAccountListSize() > 0) {
// Already have an account.
if (CurrentAccountToMigrate.accountToMigrateListSize > 0)
// Do we need to migrate any accounts?
viewCoordinator.present("AccountMigrationView");
else
// Okay now just start the client normally.
viewCoordinator.present("WelcomePage");
} else {
// No account, so start the wizard.
viewCoordinator.present("WizardView");
}
// Set up the event filter for macOS.
if (Qt.platform.os.toString() === "osx") {
MainApplication.setEventFilter();
}
// Quiet check for updates on start if set to.
if (Qt.platform.os.toString() === "windows") {
if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) {
AppVersionManager.checkForUpdates(true);
AppVersionManager.setAutoUpdateCheck(true);
}
}
// Handle a start URI if set as start option.
MainApplication.handleUriAction();
// This will allow visible to become true if not starting minimized.
windowSettingsLoaded = true;
}
Component.onCompleted: {
// QWK: setup
if (useFrameless) {
windowAgent.setup(appWindow);
}
mainViewLoader.active = true;
// Dbus error handler for Linux.
if (Qt.platform.os.toString() !== "windows" && Qt.platform.os.toString() !== "osx")
DBusErrorHandler.setActive(true);
}
Loader {
id: mainApplicationLoader
id: mainViewLoader
active: false
source: "qrc:/mainview/MainView.qml"
anchors.fill: parent
z: -1
onLoaded: initMainView(item)
}
asynchronous: true
visible: status == Loader.Ready
// Use this as a parent for fullscreen items.
Item {
id: fullscreenContainer
anchors.fill: parent
}
Connections {
id: connectionMigrationEnded
// QWK: Provide spacing for widgets that may be occluded by the system buttons.
QtObject {
id: qwkSystemButtonSpacing
readonly property bool isMacOS: Qt.platform.os.toString() === "osx"
readonly property bool isFullscreen: layoutManager.isFullScreen
// macOS buttons are on the left.
readonly property real left: useFrameless && isMacOS && viewCoordinator.isInSinglePaneMode ? 80 : 0
// Windows and Linux buttons are on the right.
readonly property real right: useFrameless && !isMacOS && !isFullscreen ? sysBtnsLoader.width + 24 : 0
}
target: CurrentAccountToMigrate
function onAccountNeedsMigration(accountId) {
viewCoordinator.present("AccountMigrationView");
}
function onAllMigrationsFinished() {
viewCoordinator.dismiss("AccountMigrationView");
startClient();
}
// QWK: Window Title bar
Item {
id: titleBar
height: JamiTheme.qwkTitleBarHeight
anchors {
top: parent.top
right: parent.right
left: parent.left
}
// Set `visible = false` when loading a new QML file.
onSourceChanged: windowSettingsLoaded = false
onLoaded: {
if (UtilsAdapter.getAccountListSize() === 0) {
layoutManager.restoreWindowSettings();
if (!viewCoordinator.rootView)
// Set the viewCoordinator's root item.
viewCoordinator.init(item);
viewCoordinator.present("WizardView");
} else {
// Main window, load any valid app settings, and allow the
// layoutManager to handle as much as possible.
layoutManager.restoreWindowSettings();
// Present the welcome view once the viewCoordinator is setup.
viewCoordinator.initialized.connect(function () {
viewCoordinator.preload("SidePanel");
viewCoordinator.preload("SettingsSidePanel");
viewCoordinator.present("WelcomePage");
viewCoordinator.preload("ConversationView");
});
if (!viewCoordinator.rootView)
// Set the viewCoordinator's root item.
viewCoordinator.init(item);
if (CurrentAccountToMigrate.accountToMigrateListSize > 0)
viewCoordinator.present("AccountMigrationView");
// On Windows and Linux, use custom system buttons.
Loader {
id: sysBtnsLoader
active: Qt.platform.os.toString() !== "osx" && useFrameless
height: titleBar.height
anchors {
top: parent.top
right: parent.right
// Note: leave these margins, they prevent image scaling artifacts
topMargin: 1
rightMargin: 1
}
if (Qt.platform.os.toString() === "osx") {
MainApplication.setEventFilter();
}
// This will trigger `visible = true`.
windowSettingsLoaded = true;
// Quiet check for updates on start if set to.
if (Qt.platform.os.toString() === "windows") {
if (UtilsAdapter.getAppValue(Settings.AutoUpdate)) {
AppVersionManager.checkForUpdates(true);
AppVersionManager.setAutoUpdateCheck(true);
}
}
// Handle a start URI if set as start option.
MainApplication.handleUriAction();
source: "qrc:/commoncomponents/QWKSystemButtonGroup.qml"
}
}
// QWK: Main interop component.
WindowAgent {
id: windowAgent
}
Connections {
target: LRCInstance
@ -339,11 +394,5 @@ ApplicationWindow {
}
}
onClosing: root.close()
Component.onCompleted: {
startClient();
if (Qt.platform.os.toString() !== "windows" && Qt.platform.os.toString() !== "osx")
DBusErrorHandler.setActive(true);
}
onClosing: appWindow.close()
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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
@ -24,14 +24,6 @@ import "commoncomponents"
QtObject {
id: root
required property QtObject viewManager
signal initialized
function requestAppWindowWizardView() {
viewCoordinator.present("WizardView");
}
// A map of view names to file paths for QML files that define each view.
property variant resources: {
"SidePanel": "mainview/components/SidePanel.qml",
@ -47,12 +39,44 @@ QtObject {
// The `main` view of the application window.
property StackView rootView
property var currentViewName: rootView && rootView.currentItem && rootView.currentItem.objectName || null
readonly property Item currentView: rootView && rootView.currentItem || null
readonly property var currentViewName: currentView && currentView.objectName || null
readonly property bool isDualPane: currentView && currentView instanceof DualPaneView
readonly property bool isInSinglePaneMode: !isDualPane || currentView.isSinglePane
readonly property bool isRTL: Qt.application.layoutDirection === Qt.RightToLeft
// A list of the current visible views. This could be a single view or two views in
// dual pane mode. The list is ordered [minor, major] where major is the view on the
// right side when not in RTL and should represent the main or content-type view.
readonly property var visibleViews: {
if (!currentView)
return []
if (isDualPane) {
if (isInSinglePaneMode)
return [currentView.rightPaneItem]
return [currentView.leftPaneItem, currentView.rightPaneItem]
}
return [currentView]
}
// Aggregate this info and expose it as a single string for convenience.
// JSON indented by 2 spaces.
readonly property string currentViewInfo: {
var info = {
currentViewName: currentViewName,
isDualPane: isDualPane,
isInSinglePaneMode: isInSinglePaneMode,
visibleViews: visibleViews.map(function(view) {
return view && view.objectName || null;
}),
visibleViewWidths: visibleViews.map(function(view) {
return view && view.width || null;
}),
};
return JSON.stringify(info, null, 2);
}
function init(mainStackView) {
rootView = Qt.createQmlObject(`import QtQuick; import QtQuick.Controls
StackView { anchors.fill: parent }`, mainStackView);
initialized();
}
function deinit() {
@ -171,6 +195,8 @@ QtObject {
var objectName = view ? view.objectName : obj.objectName;
if (!viewManager.destroyView(resources[objectName])) {
print("could not destroy view:", objectName);
} else {
print("destroyed view:", objectName);
}
} else
view.dismissed();
@ -197,8 +223,20 @@ QtObject {
}
}
function getView(viewName) {
return viewManager.getView(viewName);
function getView(viewName, forceCreate = false) {
// If the view is already loaded, return it.
var view = viewManager.getView(viewName);
if (view)
return view;
if (!forceCreate)
return null;
// Otherwise, create it.
view = viewManager.createView(resources[viewName], null);
if (!view) {
console.log("Failed to load view: " + viewName);
return null;
}
return view;
}
// Load a view without presenting it.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Author: Yang Wang <yang.yang@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -137,4 +137,11 @@ AppSettingsManager::loadTranslations()
}
Q_EMIT retranslate();
loadHistory();
}
void
AppSettingsManager::loadHistory()
{
Q_EMIT reloadHistory();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -20,20 +20,29 @@
#pragma once
#include "utils.h"
#include <QMetaEnum>
#include <QObject>
#include <QString>
#include <QStandardPaths>
#include <QWindow> // for QWindow::AutomaticVisibility
#include <QSettings>
#include <QDir>
#include <QTranslator>
extern const QString defaultDownloadPath;
// clang-format off
#define KEYS \
// Define USE_FRAMELESS_WINDOW_DEFAULT based on the platform
#ifdef Q_OS_LINUX
#define USE_FRAMELESS_WINDOW_DEFAULT false
#else
#define USE_FRAMELESS_WINDOW_DEFAULT true
#endif
// Common key-value pairs for both APPSTORE and non-APPSTORE builds
#define COMMON_KEYS \
X(MinimizeOnClose, false) \
X(DownloadPath, defaultDownloadPath) \
X(ScreenshotPath, {}) \
@ -64,11 +73,20 @@ extern const QString defaultDownloadPath;
X(ShowMardownOption, false) \
X(ChatViewEnterIsNewLine, false) \
X(ShowSendOption, false) \
X(EnablePtt, false) \
X(PttKeys, 32) \
X(UseFramelessWindow, USE_FRAMELESS_WINDOW_DEFAULT)
#ifdef APPSTORE
#define KEYS COMMON_KEYS
#else
// Additional key-value pairs for non-APPSTORE builds including donation
// related settings.
#define KEYS COMMON_KEYS \
X(Donation2023VisibleDate, "2023-11-27 05:00") \
X(IsDonationVisible, true) \
X(Donation2023EndDate, "2024-01-31 00:00") \
X(EnablePtt, false) \
X(PttKeys, 32)
X(Donation2023EndDate2, "2024-04-01 00:00")
#endif
/*
* A class to expose settings keys in both c++ and QML.
* Note: this is using a non-constructable class instead of a
@ -106,8 +124,9 @@ public:
default: return {};
}
}
private:
Settings() = delete;
Settings() = delete;
};
Q_DECLARE_METATYPE(Settings::Key)
// clang-format on
@ -130,9 +149,11 @@ public:
QString getLanguage();
void loadTranslations();
void loadHistory();
Q_SIGNALS:
void retranslate();
void reloadHistory();
private:
QSettings* settings_;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author : Edric Ladent Milaret<edric.ladent - milaret @savoirfairelinux.com>
* Author : Andreas Traczyk<andreas.traczyk @savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>

View File

@ -1,5 +1,5 @@
/*!
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -27,7 +27,8 @@ AvatarRegistry::AvatarRegistry(LRCInstance* instance, QObject* parent)
connect(lrcInstance_,
&LRCInstance::currentAccountIdChanged,
this,
&AvatarRegistry::connectAccount);
&AvatarRegistry::connectAccount,
Qt::DirectConnection);
connect(&lrcInstance_->accountModel(),
&AccountModel::profileUpdated,

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
* Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
* Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
@ -314,7 +314,7 @@ CallAdapter::onCallStatusChanged(const QString& callId, int code)
currentConfSubcalls_.clear();
return;
}
} else {
} else if (currentConfSubcalls_.size() >= 2) {
// okay, still a conference, so just update the subcall list and this call
saveConferenceSubcalls();
Q_EMIT lrcInstance_->conversationUpdated(currentConvInfo.uid, accountId_);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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
@ -35,10 +35,12 @@ Rectangle {
signal dismissed
Component.onCompleted: {
console.debug("Created", objectName);
if (managed)
presented();
}
Component.onDestruction: {
console.debug("Destroyed", objectName);
if (managed)
dismissed();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -54,6 +54,11 @@ SBSMessageBase {
function onActiveCallsChanged() {
root.isActive = LRCInstance.indexOfActiveCall(ConfId, ActionUri, DeviceId) !== -1;
if (root.isActive) {
bubble.mask.border.color = CurrentConversation.color;
bubble.mask.border.width = 1.5;
bubble.mask.z = -2;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
@ -34,17 +34,19 @@ Loader {
property bool showTime
property bool showDay
property int timestamp: Timestamp
property string formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
property string formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
property string formattedTime: MessagesAdapter.getFormattedTime(root.timestamp)
property string formattedDay: MessagesAdapter.getFormattedDay(root.timestamp)
property int seq: MsgSeq.single
property string author: Author
property string body: Body
property var transferStatus: Status
width: ListView.view ? ListView.view.width : 0
sourceComponent: {
if (Status === Interaction.Status.TRANSFER_FINISHED) {
mediaInfo = MessagesAdapter.getMediaInfo(Body)
if (root.transferStatus === Interaction.Status.TRANSFER_FINISHED) {
mediaInfo = MessagesAdapter.getMediaInfo(root.body)
if (Object.keys(mediaInfo).length !== 0 && WITH_WEBENGINE)
return localMediaMsgComp
}
@ -61,8 +63,9 @@ Loader {
SBSMessageBase {
id: dataTransferItem
property var transferStats: MessagesAdapter.getTransferStats(Id, Status)
property bool canOpen: Status === Interaction.Status.TRANSFER_FINISHED || isOutgoing
transferId: Id
property var transferStats: MessagesAdapter.getTransferStats(transferId, root.transferStatus)
property bool canOpen: root.transferStatus === Interaction.Status.TRANSFER_FINISHED || isOutgoing
property real maxMsgWidth: root.width - senderMargin -
2 * hPadding - avatarBlockWidth
- buttonsLoader.width - 24 - 6 - 24
@ -73,14 +76,11 @@ Loader {
author: Author
location: Body
transferName: TransferName
transferId: Id
readers: Readers
timestamp: root.timestamp
formattedTime: root.formattedTime
formattedDay: root.formattedTime
extraHeight: progressBar.visible ? 18 : 0
Component.onCompleted: bubble.timestampItem.visible = false
innerContent.children: [
RowLayout {
@ -92,7 +92,7 @@ Loader {
enabled: canOpen
onHoveredChanged: {
if (enabled && hovered) {
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(Body)
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(location)
} else {
dataTransferItem.hoveredLink = ""
}
@ -103,78 +103,64 @@ Loader {
}
Loader {
id: buttonsLoader
objectName: "buttonsLoader"
property string iconSourceA
property string iconSourceB
property string iconSource
Layout.margins: 12
Layout.margins: 8
sourceComponent: {
switch (Status) {
switch (root.transferStatus) {
case Interaction.Status.TRANSFER_CREATED:
case Interaction.Status.TRANSFER_FINISHED:
iconSource = JamiResources.link_black_24dp_svg
return terminatedComp
case Interaction.Status.TRANSFER_CANCELED:
case Interaction.Status.TRANSFER_ERROR:
case Interaction.Status.TRANSFER_UNJOINABLE_PEER:
case Interaction.Status.TRANSFER_TIMEOUT_EXPIRED:
iconSourceA = JamiResources.error_outline_black_24dp_svg
return terminatedComp
case Interaction.Status.TRANSFER_CREATED:
case Interaction.Status.TRANSFER_FINISHED:
iconSourceA = JamiResources.link_black_24dp_svg
return terminatedComp
case Interaction.Status.TRANSFER_AWAITING_HOST:
iconSourceA = JamiResources.download_black_24dp_svg
iconSourceB = JamiResources.close_black_24dp_svg
iconSource = JamiResources.download_black_24dp_svg
return optionsComp
case Interaction.Status.TRANSFER_ONGOING:
iconSourceA = JamiResources.close_black_24dp_svg
iconSource = JamiResources.close_black_24dp_svg
return optionsComp
default:
iconSourceA = JamiResources.error_outline_black_24dp_svg
iconSource = JamiResources.error_outline_black_24dp_svg
return terminatedComp
}
}
Component {
id: terminatedComp
ResponsiveImage {
source: buttonsLoader.iconSourceA
Layout.leftMargin: 12
Layout.preferredWidth: 24
Layout.preferredHeight: 24
color: UtilsAdapter.luma(bubble.color)
? JamiTheme.chatviewTextColorLight
: JamiTheme.chatviewTextColorDark
Control {
width: 50
height: 50
padding: 13
background: Rectangle {
color: JamiTheme.blackColor
opacity: 0.15
radius: msgRadius
}
contentItem: ResponsiveImage {
source: buttonsLoader.iconSource
color: UtilsAdapter.luma(bubble.color) ? JamiTheme.fileIconLightColor : JamiTheme.fileIconDarkColor
}
}
}
Component {
id: optionsComp
ColumnLayout {
Layout.leftMargin: 12
PushButton {
source: buttonsLoader.iconSourceA
normalColor: JamiTheme.chatviewBgColor
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
switch (Status) {
case Interaction.Status.TRANSFER_ONGOING:
return MessagesAdapter.cancelFile(Id)
case Interaction.Status.TRANSFER_AWAITING_HOST:
return MessagesAdapter.acceptFile(Id)
default: break
}
}
}
PushButton {
visible: !CurrentConversation.isSwarm
height: visible * implicitHeight
source: buttonsLoader.iconSourceB
normalColor: JamiTheme.chatviewBgColor
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
switch (Status) {
case Interaction.Status.TRANSFER_AWAITING_HOST:
return MessagesAdapter.cancelFile(Id)
default: break
}
PushButton {
source: buttonsLoader.iconSource
normalColor: JamiTheme.chatviewBgColor
imageColor: JamiTheme.chatviewButtonColor
onClicked: {
if (root.transferStatus === Interaction.Status.TRANSFER_ONGOING) {
return MessagesAdapter.cancelFile(transferId)
} else {
return MessagesAdapter.acceptFile(transferId)
}
}
}
@ -182,17 +168,14 @@ Loader {
}
Column {
Layout.rightMargin: 24
spacing: 6
spacing: 4
TextEdit {
id: transferName
width: Math.min(implicitWidth, maxMsgWidth)
topPadding: 10
text: CurrentConversation.isSwarm ?
TransferName :
Body
transferName :
location
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
font.weight: Font.DemiBold
font.pointSize: 11
renderType: Text.NativeRendering
readOnly: true
@ -206,7 +189,7 @@ Loader {
Qt.ArrowCursor
onClicked: function (mouse) {
if (canOpen) {
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(Body)
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(location)
Qt.openUrlExternally(new Url(dataTransferItem.hoveredLink))
} else {
dataTransferItem.hoveredLink = ""
@ -220,7 +203,7 @@ Loader {
width: Math.min(implicitWidth, maxMsgWidth)
bottomPadding: 10
text: {
var res = formattedTime + " - "
var res = ""
if (transferStats.totalSize !== undefined) {
if (transferStats.progress !== 0 &&
transferStats.progress !== transferStats.totalSize) {
@ -229,7 +212,7 @@ Loader {
var totalSize = transferStats.totalSize !== 0 ? transferStats.totalSize : TotalSize
res += UtilsAdapter.humanFileSize(totalSize)
}
return res + " - " + MessagesAdapter.getStatusString(Status)
return res
}
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
font.pointSize: 10
@ -243,7 +226,7 @@ Loader {
,ProgressBar {
id: progressBar
visible: Status === Interaction.Status.TRANSFER_ONGOING
visible: root.transferStatus === Interaction.Status.TRANSFER_ONGOING
height: visible * implicitHeight
value: transferStats.progress / transferStats.totalSize
width: transferItem.width
@ -260,16 +243,18 @@ Loader {
id: localMediaMsgItem
isOutgoing: Author === CurrentAccount.uri
property var transferStats: MessagesAdapter.getTransferStats(Id, Status)
transferId: Id
property var transferStats: MessagesAdapter.getTransferStats(transferId, root.transferStatus)
showTime: root.showTime
seq: root.seq
author: Author
location: Body
transferName: TransferName
transferId: Id
readers: Readers
formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
formattedTime: MessagesAdapter.getFormattedTime(root.timestamp)
formattedDay: MessagesAdapter.getFormattedDay(root.timestamp)
property real contentWidth
Component.onCompleted: {
if (transferStats.totalSize !== undefined) {
@ -277,12 +262,20 @@ Loader {
var txt = UtilsAdapter.humanFileSize(totalSize)
}
bubble.timestampItem.timeLabel.text += " - " + txt
bubble.color = "transparent"
bubble.timestampItem.timeColor = JamiTheme.whiteColor
bubble.timestampItem.timeLabel.opacity = 1
bubble.z = 1
if (mediaInfo.isImage)
bubble.z = 1
else
timeUnderBubble = true
}
onContentWidthChanged: {
if (bubble.timestampItem.timeLabel.width > contentWidth)
timeUnderBubble = true
else {
bubble.timestampItem.timeColor = JamiTheme.whiteColor
bubble.timestampItem.timeLabel.opacity = 1
}
}
innerContent.children: [
@ -300,6 +293,9 @@ Loader {
return animatedImageComp
return avComp
}
Component {
id: avComp
@ -349,14 +345,13 @@ Loader {
radius: msgRadius
}
}
HoverHandler {
target : parent
onHoveredChanged: {
localMediaMsgItem.hoveredLink = hovered ? animatedImg.source : ""
}
cursorShape: Qt.PointingHandCursor
onWidthChanged: {
localMediaMsgItem.contentWidth = width
}
Component.onCompleted: localMediaMsgItem.bubble.imgSource = source
LinearGradient {
id: gradient
anchors.fill: parent
@ -390,6 +385,8 @@ Loader {
asynchronous: true
source: Body !== undefined ? UtilsAdapter.urlFromLocalPath(Body) : ''
Component.onCompleted: localMediaMsgItem.bubble.imgSource = source
// The sourceSize represents the maximum source dimensions.
// This should not be a dynamic binding, as property changes
// (resizing the chat view) here will trigger a reload of the image.
@ -401,12 +398,17 @@ Loader {
readonly property real aspectRatio: paintedWidth / paintedHeight
readonly property real idealWidth: innerContent.width - senderMargin
onStatusChanged: {
if (status == Image.Ready && aspectRatio) {
if (img.status == Image.Ready && aspectRatio) {
height = Qt.binding(() => JamiQmlUtils.clamp(idealWidth / aspectRatio, 64, 256))
width = Qt.binding(() => height * aspectRatio)
}
}
onWidthChanged: {
localMediaMsgItem.contentWidth = width
}
Rectangle {
color: JamiTheme.previewImageBackgroundColor
z: -1
@ -422,13 +424,6 @@ Loader {
radius: msgRadius
}
}
HoverHandler {
target : parent
onHoveredChanged: {
localMediaMsgItem.hoveredLink = hovered ? img.source : ""
}
cursorShape: Qt.PointingHandCursor
}
LinearGradient {
id: gradient

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Sébastien blin <sebastien.blin@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Albert Babí <albert.babig@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -131,7 +131,7 @@ Popup {
Repeater {
model: emojiArray.length < 15 ? emojiArray.length : 15
delegate: Text {
text: emojiArray[index]
text: emojiArray[index].body
horizontalAlignment: Text.AlignRight
font.pointSize: JamiTheme.emojiPopupFontsize
}
@ -147,7 +147,7 @@ Popup {
delegate: Button {
id: emojiButton
text: emojiArray[index]
text: emojiArray[index].body
font.pointSize: JamiTheme.emojiPopupFontsize
background.visible: false
padding: 0
@ -155,13 +155,13 @@ Popup {
Text {
visible: emojiButton.hovered
anchors.centerIn: parent
text: emojiArray[index]
text: emojiArray[index].body
font.pointSize: JamiTheme.emojiPopupFontsizeBig
z: 1
}
onClicked: {
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, emojiButton.text, msgId);
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, emojiButton.text, emojiArray[index].commitId);
if (emojiArray.length === 1)
close();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -43,7 +43,7 @@ Item {
for (const reaction of Object.entries(reactions)) {
var authorEmojiList = reaction[1];
for (var emojiIndex in authorEmojiList) {
var emoji = authorEmojiList[emojiIndex];
var emoji = authorEmojiList[emojiIndex].body;
if (emojiList.includes(emoji)) {
var findIndex = emojiList.indexOf(emoji);
if (findIndex != -1)
@ -75,7 +75,7 @@ Item {
var authorEmojiList = reaction[1];
if (CurrentAccount.uri === authorUri) {
for (var emojiIndex in authorEmojiList) {
list[index] = authorEmojiList[emojiIndex];
list[index] = authorEmojiList[emojiIndex].body;
index++;
}
return list;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Xavier Jouslin <xavier.jouslindenoray@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
* Author: Fadi Shehadeh <fadi.shehadeh@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
@ -21,7 +21,7 @@ import QtQuick.Controls
import net.jami.Models 1.1
import net.jami.Constants 1.1
Rectangle {
Control {
id: root
property string icoSource: ""
@ -32,9 +32,7 @@ Rectangle {
width: 190
height: infos.implicitHeight
color: JamiTheme.transparentColor
ColumnLayout {
contentItem: ColumnLayout {
id: infos
anchors.fill: parent
@ -79,6 +77,7 @@ Rectangle {
color: JamiTheme.textColor
wrapMode: Text.WordWrap
text: description
lineHeight: 1.3
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
* Copyright (C) 2022-2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2023 Savoir-faire Linux Inc.
* Copyright (C) 2019-2024 Savoir-faire Linux Inc.
* Author: Yang Wang <yang.wang@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
* Copyright (C) 2020-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2023 Savoir-faire Linux Inc.
* Copyright (C) 2024 Savoir-faire Linux Inc.
*
* 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2023 Savoir-faire Linux Inc.
* Copyright (C) 2021-2024 Savoir-faire Linux Inc.
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify

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