mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-10-30 07:53:33 +08:00
Compare commits
88 Commits
nightly/20
...
nightly/20
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f7e33cf33 | |||
| 73258efdf7 | |||
| a29d5f791f | |||
| 5186c27325 | |||
| 7e926a3e23 | |||
| 93cde493d8 | |||
| cb829676e3 | |||
| 112c6a4d7a | |||
| 188f487695 | |||
| 0af01cc62d | |||
| a8acc71830 | |||
| eaf409d6d3 | |||
| 42e3eeabf6 | |||
| 41cb6528c2 | |||
| b6aa9eedfa | |||
| 3c1b2c22b2 | |||
| fb660b928f | |||
| 2f163846c7 | |||
| c6f79f4132 | |||
| 6b9cb684ec | |||
| 1d0fa772e2 | |||
| 51c716d718 | |||
| 5e4556f786 | |||
| da667056fd | |||
| 9d00c4f4e3 | |||
| f5743da2d6 | |||
| 7152b51597 | |||
| 4a53397561 | |||
| d86a90207a | |||
| 7b298deee8 | |||
| 056cf14613 | |||
| 2e75dd8777 | |||
| 8bda8da414 | |||
| b7fb63ae40 | |||
| 31bd0392da | |||
| 59f3aa7c44 | |||
| 9aeb405644 | |||
| 9e1d8e3e56 | |||
| b65774add0 | |||
| c55486988f | |||
| 39833924af | |||
| a194e86d7a | |||
| 8cfd9bc3fc | |||
| bdec942d72 | |||
| 35d5595401 | |||
| 7330a87082 | |||
| 7243b10e81 | |||
| 964c8e0553 | |||
| 96c00ff019 | |||
| c8716d1113 | |||
| 630e5e9fe4 | |||
| f447327c02 | |||
| 650f98636b | |||
| b92cd902b9 | |||
| b99c2674b4 | |||
| 1524ba0177 | |||
| 5503769023 | |||
| 89354a07e1 | |||
| 69400bee2a | |||
| 0e07f9cee7 | |||
| d2eba1d91e | |||
| 78389d8c28 | |||
| e6d820850a | |||
| 0a7f9349a9 | |||
| 99254f8d02 | |||
| 010a2c4eea | |||
| 61163037d4 | |||
| 3577982a93 | |||
| 3ad0b92dcd | |||
| 91475c3a3f | |||
| 9379af23ec | |||
| 406a251c85 | |||
| 20e2852e44 | |||
| 3225f90ce8 | |||
| df3e76a1cf | |||
| c5e15d26a0 | |||
| 77e019b02b | |||
| 89bed2bf85 | |||
| 519871e458 | |||
| 0a842042b0 | |||
| 9aeb2377dc | |||
| 6ad5f4b850 | |||
| f5c63d24fb | |||
| 5cb34bd31c | |||
| e56a966de1 | |||
| acc0c97234 | |||
| 665af7c0c3 | |||
| fa51e042e5 |
@ -29,7 +29,8 @@ else()
|
||||
project(jami)
|
||||
endif()
|
||||
|
||||
include(${PROJECT_SOURCE_DIR}/extras/build/cmake/extra_tools.cmake)
|
||||
set(CMAKE_SCRIPTS_DIR ${PROJECT_SOURCE_DIR}/extras/build/cmake)
|
||||
include(${CMAKE_SCRIPTS_DIR}/extra_tools.cmake)
|
||||
|
||||
option(WITH_DAEMON_SUBMODULE "Build with daemon submodule" ON)
|
||||
option(JAMICORE_AS_SUBDIR "Build Jami-core as a subdir dependency" OFF)
|
||||
@ -117,6 +118,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
# src
|
||||
set(LIBCLIENT_SRC_DIR ${PROJECT_SOURCE_DIR}/src/libclient)
|
||||
set(APP_SRC_DIR ${PROJECT_SOURCE_DIR}/src/app)
|
||||
set(VERSION_INFO_DIR ${PROJECT_SOURCE_DIR}/src/version_info)
|
||||
# doc
|
||||
set(DOC_DIR ${PROJECT_SOURCE_DIR}/doc)
|
||||
# extras
|
||||
@ -210,6 +212,23 @@ include(FindPython3)
|
||||
find_package(Python3 3.6 REQUIRED COMPONENTS Interpreter)
|
||||
set(PYTHON_EXEC ${Python3_EXECUTABLE})
|
||||
|
||||
# Versioning and build ID generation
|
||||
set(VERSION_FILE ${CMAKE_CURRENT_BINARY_DIR}/version_info.cpp)
|
||||
# Touch the file to make sure it exists at configure time as
|
||||
# we add it to the target_sources below.
|
||||
file(TOUCH ${VERSION_FILE})
|
||||
add_custom_target(
|
||||
generate_version_info ALL
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DAPP_SOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-DAPP_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
|
||||
-DCORE_SOURCE_DIR=${DAEMON_DIR}
|
||||
-DCPP_INT_FILE=${VERSION_INFO_DIR}/version_info.cpp.in
|
||||
-P ${CMAKE_SCRIPTS_DIR}/generate_version_info.cmake
|
||||
)
|
||||
list(APPEND CLIENT_INCLUDE_DIRS ${VERSION_INFO_DIR})
|
||||
|
||||
# Resource auto-gen
|
||||
# QML and related code files
|
||||
# Check files in the app's src directory and force a reconfigure if it
|
||||
@ -247,6 +266,7 @@ set(QML_IMPORT_PATH ${QML_DIRS}
|
||||
add_definitions(-DQT_NO_KEYWORDS)
|
||||
|
||||
set(COMMON_SOURCES
|
||||
${VERSION_FILE}
|
||||
${APP_SRC_DIR}/bannedlistmodel.cpp
|
||||
${APP_SRC_DIR}/accountlistmodel.cpp
|
||||
${APP_SRC_DIR}/networkmanager.cpp
|
||||
@ -626,6 +646,9 @@ qt_add_executable(
|
||||
${QML_RESOURCES_QML}
|
||||
${SFPM_OBJECTS})
|
||||
|
||||
# Make sure we can find the generated version file
|
||||
add_dependencies(${PROJECT_NAME} generate_version_info)
|
||||
|
||||
foreach(MODULE ${QT_MODULES})
|
||||
list(APPEND QT_LIBS "Qt::${MODULE}")
|
||||
endforeach()
|
||||
@ -819,12 +842,20 @@ else()
|
||||
"-framework Security"
|
||||
compression
|
||||
resolv
|
||||
)
|
||||
)
|
||||
|
||||
set(APP_CONTAINER "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app/Contents")
|
||||
|
||||
# ringtones. Copy the entire directory to the app bundle.
|
||||
# daemon/ringtones -> Jami.app/Contents/Resources/ringtones
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${DAEMON_DIR}/ringtones
|
||||
${APP_CONTAINER}/Resources/ringtones
|
||||
)
|
||||
|
||||
# translations
|
||||
if(Qt${QT_VERSION_MAJOR}LinguistTools_FOUND)
|
||||
set(APP_CONTAINER
|
||||
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app/Contents")
|
||||
file(GLOB TS_FILES ${PROJECT_SOURCE_DIR}/translations/*.ts)
|
||||
|
||||
# Generate lproj folders.
|
||||
@ -852,26 +883,26 @@ else()
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${JAMI_VERSION}"
|
||||
MACOSX_BUNDLE_BUNDLE_VERSION "${JAMI_BUILD}"
|
||||
MACOSX_BUNDLE_COPYRIGHT "${PROJ_COPYRIGHT}")
|
||||
if(APPSTORE)
|
||||
message(STATUS "app store version")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/appstore/Jami.entitlements")
|
||||
else()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
SPARKLE_URL "${SPARKLE_URL}"
|
||||
SPARKLE_PUBLIC_KEY "${SPARKLE_PUBLIC_KEY}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/Jami.entitlements"
|
||||
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE)
|
||||
endif()
|
||||
if(DEPLOY)
|
||||
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -DQML_SRC_DIR=${SRC_DIR}
|
||||
-DMAC_DEPLOY_QT_PATH=${CMAKE_PREFIX_PATH}/bin
|
||||
-DEXE_NAME="${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app"
|
||||
-DSPARKLE_PATH=${SPARKLE_FRAMEWORK}
|
||||
-DENABLE_SPARKLE=${ENABLE_SPARKLE}
|
||||
-P ${EXTRAS_DIR}/build/cmake/macos_qt_deploy.cmake)
|
||||
endif()
|
||||
if(APPSTORE)
|
||||
message(STATUS "app store version")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/appstore/Jami.entitlements")
|
||||
else()
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
SPARKLE_URL "${SPARKLE_URL}"
|
||||
SPARKLE_PUBLIC_KEY "${SPARKLE_PUBLIC_KEY}"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "${CMAKE_CURRENT_SOURCE_DIR}/resources/entitlements/Jami.entitlements"
|
||||
XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME TRUE)
|
||||
endif()
|
||||
if(DEPLOY)
|
||||
execute_process(COMMAND
|
||||
"${CMAKE_PREFIX_PATH}/bin/macdeployqt"
|
||||
"${CMAKE_BINARY_DIR}/${PROJECT_NAME}.app"
|
||||
-qmldir=${QML_SRC_DIR})
|
||||
if(${ENABLE_SPARKLE} MATCHES true)
|
||||
file(COPY ${SPARKLE_FRAMEWORK} DESTINATION ${EXE_NAME}/Contents/Frameworks/)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE ${CLIENT_INCLUDE_DIRS})
|
||||
|
||||
@ -14,7 +14,7 @@ So, you will need to get Qt 6.6 first. For this, there is 3 methods:
|
||||
### Qt from our repo (recommended)
|
||||
|
||||
If your distribution is supported, we provide a Qt package (libqt-jami) on our repo.
|
||||
The files will be installed in `/usr/lib/libqt-jami`.
|
||||
The files will be installed to `/usr/lib/libqt-jami` on Debian-like distributions. For RPM based distributions the files will be installed to `/usr/lib64/qt-jami`.
|
||||
|
||||
#### Install libqt-jami, Ubuntu based
|
||||
|
||||
|
||||
3
JamiInstaller/.gitignore
vendored
3
JamiInstaller/.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
/obj
|
||||
/bin
|
||||
Components.wxs
|
||||
AppComponents.wxs
|
||||
CrtComponents.wxs
|
||||
|
||||
@ -3,13 +3,11 @@
|
||||
<?define Name="Jami" ?>
|
||||
<?define ExeName="Jami" ?>
|
||||
<?define AppName="Jami" ?>
|
||||
<?define Manufacturer="Savoir-Faire Linux"?>
|
||||
|
||||
<?if $(var.Configuration) = Release ?>
|
||||
<?define ReleaseDir="..\x64\Release"?>
|
||||
<?else?>
|
||||
<?define ReleaseDir="..\x64\Beta"?>
|
||||
<?endif ?>
|
||||
|
||||
<?define Manufacturer="Savoir-Faire Linux"?>
|
||||
<?define UcrtDir="C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x64"?>
|
||||
</Include>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-16"?>
|
||||
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Configuration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<DeployedProjects />
|
||||
<DirectoryMappings />
|
||||
<FileMappings />
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" InitialTargets="EnsureWixToolsetInstalled" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Project ToolsVersion="4.0"
|
||||
DefaultTargets="Build"
|
||||
InitialTargets="EnsureWixToolsetInstalled"
|
||||
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
|
||||
@ -16,7 +19,7 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>HarvestPath=..\x64\Release</DefineConstants>
|
||||
<DefineConstants>AppHarvestPath=..\x64\Release;CrtHarvestPath=$(VC_CRT_Dir)</DefineConstants>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
<CompilerAdditionalOptions>
|
||||
</CompilerAdditionalOptions>
|
||||
@ -26,7 +29,7 @@
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Beta|x64' ">
|
||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
|
||||
<DefineConstants>HarvestPath=..\x64\Beta</DefineConstants>
|
||||
<DefineConstants>AppHarvestPath=..\x64\Beta;CrtHarvestPath=$(VC_CRT_Dir)</DefineConstants>
|
||||
<SuppressPdbOutput>True</SuppressPdbOutput>
|
||||
<CompilerAdditionalOptions>
|
||||
</CompilerAdditionalOptions>
|
||||
@ -35,8 +38,8 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Product.wxs" />
|
||||
<Compile Include="StandardComponents.wxs" />
|
||||
<Compile Include="Components.wxs" />
|
||||
<Compile Include="AppComponents.wxs" />
|
||||
<Compile Include="CrtComponents.wxs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Config.wxi" />
|
||||
@ -58,13 +61,36 @@
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Localization.wxl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(WixTargetsPath)" Condition=" '$(WixTargetsPath)' != '' " />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets" Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
||||
<Target Name="EnsureWixToolsetInstalled" Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Import Project="$(WixTargetsPath)"
|
||||
Condition=" '$(WixTargetsPath)' != '' " />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets"
|
||||
Condition=" '$(WixTargetsPath)' == '' AND Exists('$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets') " />
|
||||
<Target Name="EnsureWixToolsetInstalled"
|
||||
Condition=" '$(WixTargetsImported)' != 'true' ">
|
||||
<Error Text="The WiX Toolset v3.11 (or newer) build tools must be installed to build this project. To download the WiX Toolset, see http://wixtoolset.org/releases/" />
|
||||
</Target>
|
||||
<Target Name="BeforeBuild">
|
||||
<HeatDirectory Directory="..\x64\$(Configuration)" PreprocessorVariable="var.HarvestPath" OutputFile="Components.wxs" ComponentGroupName="HeatGenerated" DirectoryRefId="APPLICATIONFOLDER" AutogenerateGuids="true" ToolPath="$(WixToolPath)" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" Transforms="HarvestFilter.xslt" />
|
||||
<HeatDirectory Directory="..\x64\$(Configuration)"
|
||||
PreprocessorVariable="var.AppHarvestPath"
|
||||
OutputFile="AppComponents.wxs"
|
||||
ComponentGroupName="AppHeatGenerated"
|
||||
DirectoryRefId="APPLICATIONFOLDER"
|
||||
AutogenerateGuids="true"
|
||||
ToolPath="$(WixToolPath)"
|
||||
SuppressFragments="true"
|
||||
SuppressRegistry="true"
|
||||
SuppressRootDirectory="true"
|
||||
Transforms="HarvestFilter.xslt" />
|
||||
<HeatDirectory Directory="$(VC_CRT_Dir)"
|
||||
PreprocessorVariable="var.CrtHarvestPath"
|
||||
OutputFile="CrtComponents.wxs"
|
||||
ComponentGroupName="CrtHeatGenerated"
|
||||
DirectoryRefId="APPLICATIONFOLDER"
|
||||
AutogenerateGuids="true"
|
||||
ToolPath="$(WixToolPath)"
|
||||
SuppressFragments="true"
|
||||
SuppressRegistry="true"
|
||||
SuppressRootDirectory="true" />
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
|
||||
@ -2,6 +2,14 @@
|
||||
<WixLocalization Culture="en-us"
|
||||
xmlns="http://schemas.microsoft.com/wix/2006/localization">
|
||||
<String Id="AdvancedWelcomeEulaDlgDescriptionPerMachine">By installing this software you agree to the terms in the license agreement</String>
|
||||
<UI Dialog="ExitDialog" Control="OptionalCheckBox" Width="10" Height="10" X="135" Y="110" />
|
||||
<UI Dialog="ExitDialog" Control="OptionalText" X="150" Y="110" />
|
||||
<UI Dialog="ExitDialog"
|
||||
Control="OptionalCheckBox"
|
||||
Width="10"
|
||||
Height="10"
|
||||
X="135"
|
||||
Y="110" />
|
||||
<UI Dialog="ExitDialog"
|
||||
Control="OptionalText"
|
||||
X="150"
|
||||
Y="110" />
|
||||
</WixLocalization>
|
||||
|
||||
@ -1,134 +1,220 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?include Config.wxi?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Product Id="*" Name="$(var.Name)" Language="1033" Version="$(fun.AutoVersion(1.0))" Manufacturer="$(var.Manufacturer)" UpgradeCode="7c45b52b-0390-4fe8-947a-3f13e82dd346">
|
||||
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine" />
|
||||
<Product Id="*"
|
||||
Name="$(var.Name)"
|
||||
Language="1033"
|
||||
Version="$(fun.AutoVersion(1.0))"
|
||||
Manufacturer="$(var.Manufacturer)"
|
||||
UpgradeCode="7c45b52b-0390-4fe8-947a-3f13e82dd346">
|
||||
<Package InstallerVersion="301"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine" />
|
||||
|
||||
<MajorUpgrade Schedule="afterInstallInitialize" AllowDowngrades="yes"/>
|
||||
<MediaTemplate EmbedCab="yes" CompressionLevel="high" MaximumUncompressedMediaSize="4" />
|
||||
<MajorUpgrade Schedule="afterInstallInitialize"
|
||||
AllowDowngrades="yes"/>
|
||||
<MediaTemplate EmbedCab="yes"
|
||||
CompressionLevel="high"
|
||||
MaximumUncompressedMediaSize="4" />
|
||||
|
||||
<!--Disables interaction of the package with the Restart Manager.-->
|
||||
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" />
|
||||
<Property Id="MSIRESTARTMANAGERCONTROL"
|
||||
Value="Disable" />
|
||||
|
||||
<!--Icon File should be in release folder(not wix project), otherwise cannot be read-->
|
||||
<Icon Id="icon.ico" SourceFile="$(var.ReleaseDir)\jami.ico" />
|
||||
<Property Id="ARPPRODUCTICON" Value="icon.ico" />
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
<Icon Id="icon.ico"
|
||||
SourceFile="$(var.ReleaseDir)\jami.ico" />
|
||||
<Property Id="ARPPRODUCTICON"
|
||||
Value="icon.ico" />
|
||||
<Property Id="ARPNOMODIFY"
|
||||
Value="1" />
|
||||
|
||||
<!-- It seems that QtWebEngineProcess.exe versioning requires us to force reinstall. -->
|
||||
<Property Id="REINSTALLMODE" Value="dms" />
|
||||
<Property Id="REINSTALLMODE"
|
||||
Value="dms" />
|
||||
|
||||
<Feature Id="ProductFeature" Title="Main" Level="1" Absent="disallow">
|
||||
<ComponentGroupRef Id="StandardComponents" Primary="yes" />
|
||||
<ComponentGroupRef Id="HeatGenerated" />
|
||||
<Feature Id="ProductFeature"
|
||||
Title="Main"
|
||||
Level="1"
|
||||
Absent="disallow">
|
||||
<ComponentGroupRef Id="MainExecutable"
|
||||
Primary="yes" />
|
||||
<ComponentGroupRef Id="AppHeatGenerated" />
|
||||
<ComponentGroupRef Id="CrtHeatGenerated" />
|
||||
<ComponentRef Id="ApplicationShortcutDesktop" />
|
||||
<ComponentRef Id="ApplicationShortcutStartMenu" />
|
||||
<ComponentRef Id="RegistryEntries" />
|
||||
<ComponentRef Id="URLProtocolRegistryEntries" />
|
||||
</Feature>
|
||||
|
||||
<!--Visual C++ Redist merge module-->
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Merge Id="VCRedist" SourceFile="$(env.VCRedistMergeModule)" DiskId="1" Language="0" />
|
||||
</DirectoryRef>
|
||||
<Feature Id="VCRedist" Title="Visual C++ Runtime" AllowAdvertise="no" Display="hidden" Level="1">
|
||||
<MergeRef Id="VCRedist"/>
|
||||
</Feature>
|
||||
|
||||
<SetProperty After="FindRelatedProducts" Id="FirstInstall" Value="true">
|
||||
<SetProperty After="FindRelatedProducts"
|
||||
Id="FirstInstall"
|
||||
Value="true">
|
||||
NOT Installed AND NOT WIX_UPGRADE_DETECTED AND NOT WIX_DOWNGRADE_DETECTED
|
||||
</SetProperty>
|
||||
<SetProperty After="SetFirstInstall" Id="Upgrading" Value="true">
|
||||
<SetProperty After="SetFirstInstall"
|
||||
Id="Upgrading"
|
||||
Value="true">
|
||||
WIX_UPGRADE_DETECTED AND NOT (REMOVE="ALL")
|
||||
</SetProperty>
|
||||
<SetProperty After="RemoveExistingProducts" Id="RemovingForUpgrade" Sequence="execute" Value="true">
|
||||
(REMOVE="ALL") AND UPGRADINGPRODUCTCODE
|
||||
<SetProperty After="RemoveExistingProducts"
|
||||
Id="RemovingForUpgrade"
|
||||
Sequence="execute"
|
||||
Value="true"> (REMOVE="ALL") AND UPGRADINGPRODUCTCODE
|
||||
</SetProperty>
|
||||
<SetProperty After="SetUpgrading" Id="Uninstalling" Value="true">
|
||||
<SetProperty After="SetUpgrading"
|
||||
Id="Uninstalling"
|
||||
Value="true">
|
||||
Installed AND (REMOVE="ALL") AND NOT (WIX_UPGRADE_DETECTED OR UPGRADINGPRODUCTCODE)
|
||||
</SetProperty>
|
||||
<SetProperty After="SetUninstalling" Id="Maintenance" Value="true">
|
||||
<SetProperty After="SetUninstalling"
|
||||
Id="Maintenance"
|
||||
Value="true">
|
||||
Installed AND NOT Upgrading AND NOT Uninstalling AND NOT UPGRADINGPRODUCTCODE
|
||||
</SetProperty>
|
||||
|
||||
<!--SetDirectory of APPLICATIONFOLDER -->
|
||||
<SetDirectory Id="APPLICATIONFOLDER" Value="[ProgramFiles64Folder][ApplicationFolderName]">APPLICATIONFOLDER=""</SetDirectory>
|
||||
<SetProperty Id="ARPINSTALLLOCATION" Value="[APPLICATIONFOLDER]" After="CostFinalize" />
|
||||
<SetDirectory Id="APPLICATIONFOLDER"
|
||||
Value="[ProgramFiles64Folder][ApplicationFolderName]">APPLICATIONFOLDER=""</SetDirectory>
|
||||
<SetProperty Id="ARPINSTALLLOCATION"
|
||||
Value="[APPLICATIONFOLDER]"
|
||||
After="CostFinalize" />
|
||||
|
||||
<UIRef Id="CustomUI" />
|
||||
<WixVariable Id="WixUIInfoIcon" Value="icon.ico"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="top-banner.bmp" />
|
||||
<WixVariable Id="WixUIDialogBmp" Value="main-banner.bmp" />
|
||||
<WixVariable Id="WixUISupportPerUser" Value="0" />
|
||||
<WixVariable Id="WixUIInfoIcon"
|
||||
Value="icon.ico"/>
|
||||
<WixVariable Id="WixUIBannerBmp"
|
||||
Value="top-banner.bmp" />
|
||||
<WixVariable Id="WixUIDialogBmp"
|
||||
Value="main-banner.bmp" />
|
||||
<WixVariable Id="WixUISupportPerUser"
|
||||
Value="0" />
|
||||
|
||||
<CustomAction Id="RemoveOldJamiFiles"
|
||||
Directory="APPLICATIONFOLDER"
|
||||
ExeCommand="cmd /c "del vc_redist.x64.exe; del uninstall.exe; del WinSparkle.dll;""
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
HideTarget="no"
|
||||
Impersonate="no"/>
|
||||
Directory="APPLICATIONFOLDER"
|
||||
ExeCommand="cmd /c "del vc_redist.x64.exe; del uninstall.exe; del WinSparkle.dll;""
|
||||
Execute="deferred"
|
||||
Return="ignore"
|
||||
HideTarget="no"
|
||||
Impersonate="no"/>
|
||||
|
||||
<Property Id="QtExecCmdLine"
|
||||
Value='"[APPLICATIONFOLDER]/$(var.ExeName).exe" --term'/>
|
||||
Value='"[APPLICATIONFOLDER]/$(var.ExeName).exe" --term'/>
|
||||
<CustomAction Id="TerminateAppProcess"
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="CAQuietExec"
|
||||
Execute="immediate"
|
||||
Return="ignore"/>
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="CAQuietExec"
|
||||
Execute="immediate"
|
||||
Return="ignore"/>
|
||||
</Product>
|
||||
|
||||
<Fragment Id="DirectoryStructure">
|
||||
<Directory Id="TARGETDIR" Name="SourceDir">
|
||||
<Directory Id="TARGETDIR"
|
||||
Name="SourceDir">
|
||||
<Directory Id="ProgramFiles64Folder">
|
||||
<Directory Id="APPLICATIONFOLDER" Name="$(var.Name)" />
|
||||
<Directory Id="APPLICATIONFOLDER"
|
||||
Name="$(var.Name)" />
|
||||
</Directory>
|
||||
<Directory Id="DesktopFolder" Name="Desktop" />
|
||||
<Directory Id="DesktopFolder"
|
||||
Name="Desktop" />
|
||||
<Directory Id="ProgramMenuFolder">
|
||||
<Directory Id="ApplicationProgramsFolder" />
|
||||
</Directory>
|
||||
<Directory Id="WindowsFolder" Name="WINDOWS"/>
|
||||
<Directory Id="WindowsFolder"
|
||||
Name="WINDOWS"/>
|
||||
</Directory>
|
||||
</Fragment>
|
||||
|
||||
<Fragment>
|
||||
<ComponentGroup Id="MainExecutable"
|
||||
Directory="APPLICATIONFOLDER">
|
||||
<Component Id="cmp9CFEE34E3A162AB05264E8B756EC1DEC"
|
||||
Guid="*">
|
||||
<File Id="fileMain.exe"
|
||||
KeyPath="yes"
|
||||
Source="$(var.ReleaseDir)\$(var.ExeName).exe" />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
|
||||
<Fragment Id="Shortcuts">
|
||||
<DirectoryRef Id="DesktopFolder">
|
||||
<Component Id="ApplicationShortcutDesktop" Guid="*" Win64="yes">
|
||||
<Shortcut Id="ApplicationShortcutDesktop" Name="$(var.Name)" Description="Launch $(var.Name)" Target="[#fileMain.exe]" WorkingDirectory="INSTALLFOLDER" />
|
||||
<RemoveFolder Id="DesktopFolder" On="uninstall" />
|
||||
<RegistryValue Root="HKCU" Key="Software\jami.net\$(var.Name)" Name="desktop" Type="integer" Value="1" KeyPath="yes" />
|
||||
<Component Id="ApplicationShortcutDesktop"
|
||||
Guid="*"
|
||||
Win64="yes">
|
||||
<Shortcut Id="ApplicationShortcutDesktop"
|
||||
Name="$(var.Name)"
|
||||
Description="Launch $(var.Name)"
|
||||
Target="[#fileMain.exe]"
|
||||
WorkingDirectory="INSTALLFOLDER" />
|
||||
<RemoveFolder Id="DesktopFolder"
|
||||
On="uninstall" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\jami.net\$(var.Name)"
|
||||
Name="desktop"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
KeyPath="yes" />
|
||||
<Condition>FirstInstall</Condition>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
|
||||
<DirectoryRef Id="ApplicationProgramsFolder">
|
||||
<Component Id="ApplicationShortcutStartMenu" Guid="*" Win64="yes">
|
||||
<Shortcut Id="ApplicationShortcutStartMenu" Name="$(var.Name)" Description="Launch $(var.Name)" Target="[#fileMain.exe]" WorkingDirectory="INSTALLFOLDER" />
|
||||
<RemoveFolder Id="StartMenuFolder" On="uninstall" />
|
||||
<RegistryValue Root="HKCU" Key="Software\jami.net\$(var.Name)" Name="startmenu" Type="integer" Value="1" KeyPath="yes" />
|
||||
<Component Id="ApplicationShortcutStartMenu"
|
||||
Guid="*"
|
||||
Win64="yes">
|
||||
<Shortcut Id="ApplicationShortcutStartMenu"
|
||||
Name="$(var.Name)"
|
||||
Description="Launch $(var.Name)"
|
||||
Target="[#fileMain.exe]"
|
||||
WorkingDirectory="INSTALLFOLDER" />
|
||||
<RemoveFolder Id="StartMenuFolder"
|
||||
On="uninstall" />
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\jami.net\$(var.Name)"
|
||||
Name="startmenu"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
KeyPath="yes" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
</Fragment>
|
||||
|
||||
<Fragment Id="OtherRegistryEntries">
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Component Id="RegistryEntries" Guid="*" Win64="yes">
|
||||
<RegistryValue Root="HKCU" Key="Software\jami.net\$(var.AppName)" Name="hasRun" Type="integer" Value="0" KeyPath="yes" />
|
||||
<Component Id="RegistryEntries"
|
||||
Guid="*"
|
||||
Win64="yes">
|
||||
<RegistryValue Root="HKCU"
|
||||
Key="Software\jami.net\$(var.AppName)"
|
||||
Name="hasRun"
|
||||
Type="integer"
|
||||
Value="0"
|
||||
KeyPath="yes" />
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
</Fragment>
|
||||
|
||||
<Fragment Id="URLProtocol">
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Component Id="URLProtocolRegistryEntries" Guid="*" Win64="yes">
|
||||
<RegistryKey Root="HKCR" Key="jami" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string" Name="URL Protocol" Value="" />
|
||||
<RegistryValue Type="string" Value="URL:jami"/>
|
||||
<Component Id="URLProtocolRegistryEntries"
|
||||
Guid="*"
|
||||
Win64="yes">
|
||||
<RegistryKey Root="HKCR"
|
||||
Key="jami"
|
||||
ForceCreateOnInstall="yes"
|
||||
ForceDeleteOnUninstall="yes">
|
||||
<RegistryValue Type="string"
|
||||
Name="URL Protocol"
|
||||
Value="" />
|
||||
<RegistryValue Type="string"
|
||||
Value="URL:jami"/>
|
||||
<RegistryKey Key="DefaultIcon">
|
||||
<RegistryValue Type="string" Value="[APPLICATIONFOLDER]$(var.ExeName).exe" />
|
||||
<RegistryValue Type="string"
|
||||
Value="[APPLICATIONFOLDER]$(var.ExeName).exe" />
|
||||
</RegistryKey>
|
||||
<RegistryKey Key="shell\open\command">
|
||||
<RegistryValue Type="string" Value='"[APPLICATIONFOLDER]$(var.ExeName).exe" "%1"' />
|
||||
<RegistryValue Type="string"
|
||||
Value='"[APPLICATIONFOLDER]$(var.ExeName).exe" "%1"' />
|
||||
</RegistryKey>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
@ -137,47 +223,88 @@
|
||||
|
||||
<Fragment Id="UI">
|
||||
<UI Id="CustomUI">
|
||||
<Property Id="WixAppFolder" Value="WixPerMachineFolder" />
|
||||
<Property Id="WixAppFolder"
|
||||
Value="WixPerMachineFolder" />
|
||||
|
||||
<!--APPLICATIONFOLDER required by WixUI_Advanced, ApplicationFolderName reset APPLICATIONFOLDER path-->
|
||||
<Property Id="ApplicationFolderName" Value="$(var.Manufacturer)\$(var.AppName)" />
|
||||
<Property Id="ApplicationFolderName"
|
||||
Value="$(var.Manufacturer)\$(var.AppName)" />
|
||||
<UIRef Id="WixUI_Advanced" />
|
||||
|
||||
<!--Remove User Exit Dialog-->
|
||||
<Publish Dialog="AdvancedWelcomeEulaDlg" Control="Cancel" Property="AbortInstall" Value="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg" Control="Cancel" Property="AbortInstall" Value="1">1</Publish>
|
||||
<Publish Dialog="FeaturesDlg" Control="Cancel" Property="AbortInstall" Value="1">1</Publish>
|
||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Cancel" Property="AbortInstall" Value="1">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="Cancel" Property="AbortInstall" Value="1">1</Publish>
|
||||
<Publish Dialog="AdvancedWelcomeEulaDlg"
|
||||
Control="Cancel"
|
||||
Property="AbortInstall"
|
||||
Value="1">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg"
|
||||
Control="Cancel"
|
||||
Property="AbortInstall"
|
||||
Value="1">1</Publish>
|
||||
<Publish Dialog="FeaturesDlg"
|
||||
Control="Cancel"
|
||||
Property="AbortInstall"
|
||||
Value="1">1</Publish>
|
||||
<Publish Dialog="MaintenanceWelcomeDlg"
|
||||
Control="Cancel"
|
||||
Property="AbortInstall"
|
||||
Value="1">1</Publish>
|
||||
<Publish Dialog="MaintenanceTypeDlg"
|
||||
Control="Cancel"
|
||||
Property="AbortInstall"
|
||||
Value="1">1</Publish>
|
||||
|
||||
<!--Launch Program If Checkbox is clicked-->
|
||||
<Publish Dialog="ExitDialog" Control="Finish" Event="DoAction" Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
|
||||
<Publish Dialog="ExitDialog"
|
||||
Control="Finish"
|
||||
Event="DoAction"
|
||||
Value="LaunchApplication">WIXUI_EXITDIALOGOPTIONALCHECKBOX = 1 and NOT Installed</Publish>
|
||||
|
||||
<InstallUISequence>
|
||||
<Show Dialog="UserExit" OnExit="cancel">NOT AbortInstall = 1</Show>
|
||||
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />
|
||||
<Show Dialog="UserExit"
|
||||
OnExit="cancel">NOT AbortInstall = 1</Show>
|
||||
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder"
|
||||
After="WixSetDefaultPerMachineFolder" />
|
||||
</InstallUISequence>
|
||||
</UI>
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action='TerminateAppProcess' Before='InstallValidate'/>
|
||||
<Custom Action="RemoveOldJamiFiles" After="RemoveFiles" />
|
||||
<Custom Action="LaunchApplication_nonUI" After="InstallFinalize"> WIXNONUILAUNCH </Custom>
|
||||
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder" After="WixSetDefaultPerMachineFolder" />
|
||||
<Custom Action='TerminateAppProcess'
|
||||
Before='InstallValidate'/>
|
||||
<Custom Action="RemoveOldJamiFiles"
|
||||
After="RemoveFiles" />
|
||||
<Custom Action="LaunchApplication_nonUI"
|
||||
After="InstallFinalize"> WIXNONUILAUNCH </Custom>
|
||||
<Custom Action="Overwrite_WixSetDefaultPerMachineFolder"
|
||||
After="WixSetDefaultPerMachineFolder" />
|
||||
</InstallExecuteSequence>
|
||||
|
||||
<!--License check box text, Launch check box text (auto check)-->
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALTEXT" Value="Launch $(var.Name)" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT" Value="Launch $(var.Name)" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALTEXT"
|
||||
Value="Launch $(var.Name)" />
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOXTEXT"
|
||||
Value="Launch $(var.Name)" />
|
||||
<!--CheckBox Default Set to One-->
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX" Value="1"/>
|
||||
<Property Id="LicenseAccepted" Value="1"/>
|
||||
<Property Id="WIXUI_EXITDIALOGOPTIONALCHECKBOX"
|
||||
Value="1"/>
|
||||
<Property Id="LicenseAccepted"
|
||||
Value="1"/>
|
||||
|
||||
<Property Id="WixShellExecTarget" Value="[#fileMain.exe]" />
|
||||
<CustomAction Id="LaunchApplication" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes" />
|
||||
<CustomAction Id="LaunchApplication_nonUI" BinaryKey="WixCA" DllEntry="WixShellExec" Impersonate="yes"/>
|
||||
<CustomAction Id="Overwrite_WixSetDefaultPerMachineFolder" Property="WixPerMachineFolder" Value="[ProgramFiles64Folder][ApplicationFolderName]" Execute="immediate" />
|
||||
<Property Id="WixShellExecTarget"
|
||||
Value="[#fileMain.exe]" />
|
||||
<CustomAction Id="LaunchApplication"
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="WixShellExec"
|
||||
Impersonate="yes" />
|
||||
<CustomAction Id="LaunchApplication_nonUI"
|
||||
BinaryKey="WixCA"
|
||||
DllEntry="WixShellExec"
|
||||
Impersonate="yes"/>
|
||||
<CustomAction Id="Overwrite_WixSetDefaultPerMachineFolder"
|
||||
Property="WixPerMachineFolder"
|
||||
Value="[ProgramFiles64Folder][ApplicationFolderName]"
|
||||
Execute="immediate" />
|
||||
<!--License File-->
|
||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.ReleaseDir)\License.rtf"/>
|
||||
<WixVariable Id="WixUILicenseRtf"
|
||||
Value="$(var.ReleaseDir)\License.rtf"/>
|
||||
</Fragment>
|
||||
|
||||
</Wix>
|
||||
|
||||
@ -1,86 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Generated with WiX's heat tool using the command:
|
||||
heat.exe dir x64\Release -ag -cg ProductComponents -dr APPLICATIONFOLDER -srd -var var.ReleaseDir -out JamiInstaller\Components.wxs
|
||||
Includes:
|
||||
- the api-ms-win dlls missing parts of vc merge module for windows 7 support
|
||||
- Jami.exe with a named Id so we can reference it in Product.wxs to launch after install
|
||||
|
||||
We run heat in the prebuild step on x64\Release without Jami.exe (instead of an XSLT file), to harvest everything else.
|
||||
-->
|
||||
<?include Config.wxi?>
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
<Fragment>
|
||||
<ComponentGroup Id="StandardComponents">
|
||||
<Component Id="cmp9C61F84AF9761955FBF397AFAE21C11B" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil2089BEC9A7AB899CED5A5EE501789299" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-file-l1-2-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp03BB2697EE10869C4A329E3EA987EFAA" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil44C27F2C97596734BB3BEB7C21F7B71C" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-file-l2-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp6B6AA7AEA5A4D324A4EE7DAE1B1193E0" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil1D16BE23D323A1E37FC1FC7354A9305F" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-localization-l1-2-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpB5454FB66442C9BFD2145AE30B32D7A9" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil031B78DF53F7A3AC109410907624FC3E" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-processthreads-l1-1-1.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp9F6D22CD9B1739E4F75F92F3A07E4CA1" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filE9A3672FA504AA8E518DD72A02CD3E77" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-synch-l1-2-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp9451422B7074D46F019614C3DE73BD17" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil3C902CA2889BB8855D285C3FBABB334F" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-core-timezone-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp349250459EC2D8C328EED5138B073E7A" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil2466F3D9FBA095A007D0909040D4D688" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-conio-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpCC880F2B054A87EF5FC68232652231BF" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil605A691486569535A1C3548F7DCE753C" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-convert-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpD6CB40D5A5AFF2161B7B4B4F06F03301" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil09AE032A32E2E542A232F7941AC77320" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-environment-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpC02538029646A27A9F786AD690EB3C8E" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil7DE9C3CADCA188356922B0CBD8E313E7" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-filesystem-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp8E50197B377636123F0F1F94FFB004E7" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil584F158D11B8A380C73F1EFE8BBA92B4" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-heap-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp7F729C94A363C73DC4D91B6F48E4F859" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil4BE19B924B98D56F3155B66496D574E5" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-locale-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp7C573E66B0904BA73880788F7057AF88" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filE8495C446FA1237E92562498D20261AA" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-math-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp7A91CED53D8F6E5F20F2049B3B5CD143" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil06951EB208628753677745AF15CC12A5" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-multibyte-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp1CE713C705A95306A1D246AC3AB9DE25" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil8D102BB81768F998470C34797459E306" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-private-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp35840DFBF4D6AE827AFC4EF2A17BB3EB" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filC6C457BD901F940DCB673D271728F9FE" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-process-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpEBB86BDA48FE3B9E2043C1A80D26ACD5" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filE1B2095225B01DEFA5DA9895B432FBCB" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-runtime-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp80C8534B553078EA8B86F100FF542776" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filDAFE58019AD70832B8304DCEA534B5EE" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-stdio-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpCFC348111B5343749A2273A62421C07C" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil1F1B38DB330CA413655F715578D4BE1A" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-string-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp7D5450E04EC419244107942A00DF7DDF" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filEB03BCF3155C5BAE2C2EDBF036EB659D" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-time-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp5456679BDCC818B2E9476B416F71AAA5" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fil5B120DD384CABED37DFC2652C6462666" KeyPath="yes" Source="$(var.UcrtDir)\api-ms-win-crt-utility-l1-1-0.dll" />
|
||||
</Component>
|
||||
<Component Id="cmpF23755F862A15FFCBD109C85599B7F20" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="filD6887AD9110E4A8D49143C9A8F0B5843" KeyPath="yes" Source="$(var.UcrtDir)\ucrtbase.dll" />
|
||||
</Component>
|
||||
<Component Id="cmp9CFEE34E3A162AB05264E8B756EC1DEC" Directory="APPLICATIONFOLDER" Guid="*">
|
||||
<File Id="fileMain.exe" KeyPath="yes" Source="$(var.ReleaseDir)\$(var.ExeName).exe" />
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
6
build.py
6
build.py
@ -100,7 +100,7 @@ ZYPPER_DEPENDENCIES = [
|
||||
'speexdsp-devel', 'speex-devel', 'libdbus-c++-devel', 'jsoncpp-devel', 'yaml-cpp-devel',
|
||||
'yasm', 'libuuid-devel', 'libnettle-devel', 'libopus-devel', 'libexpat-devel',
|
||||
'libgnutls-devel', 'msgpack-c-devel', 'msgpack-cxx-devel', 'libavcodec-devel', 'libavdevice-devel', 'pcre-devel',
|
||||
'alsa-devel', 'libpulse-devel', 'libudev-devel', 'libva-devel', 'libvdpau-devel',
|
||||
'alsa-devel', 'libpulse-devel', 'libudev-devel', 'libva-devel', 'libvdpau-devel', 'pipewire-devel',
|
||||
'libopenssl-devel', 'libavutil-devel',
|
||||
]
|
||||
|
||||
@ -130,7 +130,7 @@ DNF_DEPENDENCIES = [
|
||||
'gcc-c++', 'which', 'alsa-lib-devel', 'systemd-devel', 'libuuid-devel',
|
||||
'uuid-devel', 'gnutls-devel', 'nettle-devel', 'opus-devel', 'speexdsp-devel',
|
||||
'yaml-cpp-devel', 'swig', 'jsoncpp-devel',
|
||||
'patch', 'libva-devel', 'openssl-devel', 'libvdpau-devel', 'msgpack-devel',
|
||||
'patch', 'libva-devel', 'openssl-devel', 'libvdpau-devel', 'pipewire-devel', 'msgpack-devel',
|
||||
'sqlite-devel', 'openssl-static', 'pandoc', 'nasm',
|
||||
'bzip2'
|
||||
]
|
||||
@ -154,7 +154,7 @@ APT_DEPENDENCIES = [
|
||||
'libopus-dev', 'libpcre3-dev', 'libpulse-dev', 'libssl-dev',
|
||||
'libspeex-dev', 'libspeexdsp-dev', 'libswscale-dev', 'libtool',
|
||||
'libudev-dev', 'libyaml-cpp-dev', 'sip-tester', 'swig',
|
||||
'uuid-dev', 'yasm', 'libjsoncpp-dev', 'libva-dev', 'libvdpau-dev', 'libmsgpack-dev',
|
||||
'uuid-dev', 'yasm', 'libjsoncpp-dev', 'libva-dev', 'libvdpau-dev', 'libpipewire-0.3-dev', 'libmsgpack-dev',
|
||||
'pandoc', 'nasm', 'dpkg-dev', 'libsystemd-dev'
|
||||
]
|
||||
|
||||
|
||||
2
daemon
2
daemon
Submodule daemon updated: fd2f281544...ee342157a7
34
extras/build/cmake/generate_version_info.cmake
Normal file
34
extras/build/cmake/generate_version_info.cmake
Normal file
@ -0,0 +1,34 @@
|
||||
find_package(Git QUIET REQUIRED)
|
||||
|
||||
message(STATUS "Generating version information...")
|
||||
|
||||
function(configure_version_string SOURCE_DIR VERSION_STRING_OUT)
|
||||
# Get short git SHA
|
||||
execute_process(
|
||||
COMMAND "${GIT_EXECUTABLE}" rev-parse --short HEAD
|
||||
WORKING_DIRECTORY "${SOURCE_DIR}"
|
||||
OUTPUT_VARIABLE _GIT_SHA
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Output the VERSION_STRING_OUT to the caller
|
||||
set(${VERSION_STRING_OUT} "${_GIT_SHA}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
# These need to be set to the parent scripts values for configure_file to work,
|
||||
# as it prepends CMAKE_CURRENT_SOURCE_DIR to the <input> and CMAKE_CURRENT_BINARY_DIR
|
||||
# to <output>.
|
||||
set(CMAKE_CURRENT_SOURCE_DIR ${APP_SOURCE_DIR})
|
||||
set(CMAKE_CURRENT_BINARY_DIR ${APP_BINARY_DIR})
|
||||
|
||||
# Generate the version string for the application and core
|
||||
configure_version_string(${APP_SOURCE_DIR} APP_VERSION_STRING)
|
||||
configure_version_string(${CORE_SOURCE_DIR} CORE_VERSION_STRING)
|
||||
|
||||
# Get output file names with the .in extension removed
|
||||
get_filename_component(VERSION_CPP_FILENAME ${CPP_INT_FILE} NAME_WE)
|
||||
set(VERSION_CPP_FILE "${CMAKE_CURRENT_BINARY_DIR}/${VERSION_CPP_FILENAME}.cpp")
|
||||
|
||||
message(STATUS "infiles: ${CPP_INT_FILE}")
|
||||
message(STATUS "outfiles: ${VERSION_CPP_FILE}")
|
||||
configure_file(${CPP_INT_FILE} ${VERSION_CPP_FILE})
|
||||
@ -1,7 +0,0 @@
|
||||
message("Qt deploying in dir " ${QML_SRC_DIR})
|
||||
execute_process(COMMAND "${MAC_DEPLOY_QT_PATH}/macdeployqt"
|
||||
${EXE_NAME}
|
||||
-qmldir=${QML_SRC_DIR})
|
||||
if(${ENABLE_SPARKLE} MATCHES true)
|
||||
file(COPY ${SPARKLE_PATH} DESTINATION ${EXE_NAME}/Contents/Frameworks/)
|
||||
endif()
|
||||
@ -66,6 +66,7 @@ RUN apt-get install -y -o Acquire::Retries=10 \
|
||||
libvdpau-dev \
|
||||
libssl-dev
|
||||
RUN apt-get install -y pandoc \
|
||||
libcppunit-dev \
|
||||
googletest \
|
||||
libgtest-dev \
|
||||
wget
|
||||
|
||||
@ -1,131 +1,240 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<name>Jami</name>
|
||||
<summary>Privacy-oriented voice, video, chat, and conference platform</summary>
|
||||
<summary xml:lang="hu">Adatvédelem-orientált hang-, video-, csevegés- és konferenciaplatform</summary>
|
||||
<icon type="stock">jami</icon>
|
||||
<description>
|
||||
<id>net.jami.Jami</id>
|
||||
<metadata_license>CC-BY-SA-3.0</metadata_license>
|
||||
<project_license>GPL-3.0+</project_license>
|
||||
<name>Jami</name>
|
||||
|
||||
<summary>Privacy-oriented voice, video, chat, and conference platform</summary>
|
||||
<summary xml:lang="hu">Adatvédelem-orientált hang-, video-, csevegés- és konferenciaplatform</summary>
|
||||
<icon type="stock">jami</icon>
|
||||
|
||||
<description>
|
||||
<p>
|
||||
An end-to-end encrypted secure and distributed voice, video, and
|
||||
chat communication platform that requires no central server and
|
||||
leaves the power of privacy and freedom in the hands of users.
|
||||
Jami [1], a GNU package, is software for universal and
|
||||
distributed peer-to-peer communication that respects the
|
||||
freedom and privacy of its users.
|
||||
</p>
|
||||
<p>
|
||||
Jami supports the following key features:
|
||||
Jami is the simplest and easiest way to connect with people
|
||||
(and devices) with instant messaging, audio and video calls
|
||||
over the Internet and LAN/WAN intranets.
|
||||
</p>
|
||||
<ul>
|
||||
<li>One-to-one conversations</li>
|
||||
<li>File sharing</li>
|
||||
<li>Audio calls and conferences</li>
|
||||
<li>Video calls and conferences</li>
|
||||
<li>Screen sharing in video calls and conferences</li>
|
||||
<li>Recording and sending audio messages</li>
|
||||
<li>Recording and sending video messages</li>
|
||||
<li>Functioning as a SIP phone software</li>
|
||||
</ul>
|
||||
<p>
|
||||
Client applications for GNU/Linux, Windows, macOS, iOS, Android,
|
||||
and Android TV are available, making Jami an interoperable and
|
||||
Jami is a free/libre, end-to-end encrypted, and private
|
||||
communication platform.
|
||||
</p>
|
||||
<p>
|
||||
Jami – which used to be known as Ring – is also an
|
||||
open-source alternative (to Facebook Messenger, Signal,
|
||||
Skype, Teams, Telegram, TikTok, Viber, WhatsApp, Zoom) that
|
||||
prioritizes the privacy of its users.
|
||||
</p>
|
||||
<p>
|
||||
Jami has a professional-looking design and is available for
|
||||
a wide range of platforms. Unlike the alternatives, calls
|
||||
using Jami are directly between users as it does not use
|
||||
servers to handle calls.
|
||||
</p>
|
||||
<p>
|
||||
This gives the greatest privacy as the distributed nature
|
||||
of Jami means your calls are only between participants.
|
||||
</p>
|
||||
<p>
|
||||
One-to-one and group conversations with Jami are enhanced
|
||||
with: instant messaging; audio and video calling;
|
||||
recording and sending audio and video messages;
|
||||
file transfers; screen sharing; and, location sharing.
|
||||
</p>
|
||||
<p>
|
||||
Jami can also function as a SIP client.
|
||||
</p>
|
||||
<p>
|
||||
Jami has multiple extensions [2] available:
|
||||
Audio Filter; Auto Answer; Green Screen; Watermark; and,
|
||||
Whisper Transcript.
|
||||
</p>
|
||||
<p>
|
||||
Jami can be easily deployed in organizations with the
|
||||
“Jami Account Management Server” (JAMS) [3], allowing users
|
||||
to connect with their corporate credentials or create local
|
||||
accounts. JAMS allows you to manage your own Jami community
|
||||
while taking advantage of Jami’s distributed network
|
||||
architecture.
|
||||
</p>
|
||||
<p>
|
||||
Jami is available for GNU/Linux, Windows, macOS, iOS,
|
||||
Android, and Android TV, making Jami an interoperable and
|
||||
cross-platform communication framework.
|
||||
</p>
|
||||
|
||||
<p xml:lang="hu">
|
||||
Végpontokig titkosított biztonságos és elosztott hang-, videó-
|
||||
és csevegés-kommunikációs platform, amely nem igényel központi
|
||||
kiszolgálót, és a felhasználók kezében hagyja a magánélet és a
|
||||
szabadság hatalmát.
|
||||
<p>
|
||||
Manage multiple SIP accounts, Jami accounts and JAMS
|
||||
accounts with the Jami client installed on one or multiple
|
||||
devices.
|
||||
</p>
|
||||
<p xml:lang="hu">
|
||||
A Jami a következő főbb funkciókat támogatja:
|
||||
<p>
|
||||
Jami is free, unlimited, private, advertising free,
|
||||
compatible, fast, autonomous, and anonymous.
|
||||
</p>
|
||||
<ul>
|
||||
<li xml:lang="hu">Személyes beszélgetések</li>
|
||||
<li xml:lang="hu">Fájlmegosztás</li>
|
||||
<li xml:lang="hu">Hanghívások és konferenciák</li>
|
||||
<li xml:lang="hu">Videohívások és konferenciák</li>
|
||||
<li xml:lang="hu">Képernyőmegosztás videohívásokban és
|
||||
konferenciákon</li>
|
||||
<li xml:lang="hu">Hangüzenetek rögzítése és küldése</li>
|
||||
<li xml:lang="hu">Videoüzenetek rögzítése és küldése</li>
|
||||
<li xml:lang="hu">SIP-telefonszoftverként működik</li>
|
||||
</ul>
|
||||
<p xml:lang="hu">
|
||||
Elérhetők a GNU/Linux, Windows, macOS, iOS, Android és Android TV
|
||||
ügyfélalkalmazásai, így a Jami interoperábilis és többplatformos
|
||||
kommunikációs keretrendszerré válik.
|
||||
<p>
|
||||
[1] https://jami.net/
|
||||
</p>
|
||||
<p>
|
||||
[2] https://jami.net/extensions/
|
||||
</p>
|
||||
<p>
|
||||
[3] https://jami.biz/
|
||||
</p>
|
||||
</description>
|
||||
|
||||
</description>
|
||||
<description xml:lang="hu">
|
||||
<p>
|
||||
A Jami [1], egy GNU-csomag, egy univerzális és elosztott
|
||||
társ-társ kommunikációra szolgáló szoftver, amely
|
||||
tiszteletben tartja a felhasználók szabadságát és
|
||||
magánéletét.
|
||||
</p>
|
||||
<p>
|
||||
A Jami a legegyszerűbb és legegyszerűbb módja annak, hogy
|
||||
azonnali üzenetküldéssel, hang- és videohívásokkal
|
||||
kapcsolódjon az emberekhez (és eszközökhöz) az interneten és
|
||||
a LAN/WAN intraneteken keresztül.
|
||||
</p>
|
||||
<p>
|
||||
A Jami egy ingyenes, teljes körűen titkosított és privát
|
||||
kommunikációs platform.
|
||||
</p>
|
||||
<p>
|
||||
A Jami – amelyet korábban Ring néven ismertek – egy nyílt
|
||||
forráskódú alternatíva is (a Facebook Messenger, a Signal,
|
||||
a Skype, a Teams, a Telegram, a TikTok, a Viber, a WhatsApp,
|
||||
a Zoom számára), amely előtérbe helyezi a felhasználók
|
||||
magánéletét.
|
||||
</p>
|
||||
<p>
|
||||
A Jami professzionális megjelenésű, és platformok széles
|
||||
skálájához elérhető. Az alternatívákkal ellentétben a Jami-t
|
||||
használó hívások közvetlenül a felhasználók között zajlanak,
|
||||
mivel nem használ kiszolgálókat a hívások kezelésére.
|
||||
</p>
|
||||
<p>
|
||||
Ez biztosítja a legnagyobb magánéletet, mivel a Jami
|
||||
elosztott jellege azt jelenti, hogy a hívások csak a
|
||||
résztvevők között zajlanak.
|
||||
</p>
|
||||
<p>
|
||||
A Jamival folytatott személyes és csoportos beszélgetéseket
|
||||
a következők javítják: azonnali üzenetküldés; hang- és
|
||||
videohívások; hang- és videoüzenetek rögzítése és küldése;
|
||||
fájlátvitel; képernyőmegosztás; és helymegosztás.
|
||||
</p>
|
||||
<p>
|
||||
A Jami SIP-ügyfélként is működhet.
|
||||
</p>
|
||||
<p>
|
||||
A Jami-nek több bővítménye [2] is elérhető: hangszűrő;
|
||||
automatikus válasz; zöld képernyő; vízjel; és, suttogó
|
||||
átirat.
|
||||
</p>
|
||||
<p>
|
||||
A Jami könnyen telepíthető a szervezetekben
|
||||
a „Jami fiókkezelő kiszolgálóval” (JAMS) [3], amely lehetővé
|
||||
teszi a felhasználók számára, hogy csatlakozzanak vállalati
|
||||
hitelesítő adataikhoz, vagy helyi fiókokat hozzanak létre.
|
||||
A JAMS lehetővé teszi saját Jami közösségének kezelését,
|
||||
miközben kihasználja a Jami elosztott hálózati
|
||||
architektúráját.
|
||||
</p>
|
||||
<p>
|
||||
A Jami elérhető GNU/Linux, Windows, macOS, iOS, Android és
|
||||
Android TV rendszereken, így a Jami egy interoperábilis és
|
||||
platformok közötti kommunikációs keretrendszer.
|
||||
</p>
|
||||
<p>
|
||||
Kezeljen több SIP-fiókot, Jami-fiókot és JAMS-fiókot az egy
|
||||
vagy több eszközre telepített Jami-ügyféllel.
|
||||
</p>
|
||||
<p>
|
||||
A Jami ingyenes, korlátlan, privát, reklámmentes,
|
||||
kompatibilis, gyors, autonóm és névtelen.
|
||||
</p>
|
||||
<p>
|
||||
[1] https://jami.net/hu/
|
||||
</p>
|
||||
<p>
|
||||
[2] https://jami.net/hu/extensions/
|
||||
</p>
|
||||
<p>
|
||||
[3] https://jami.biz/
|
||||
</p>
|
||||
</description>
|
||||
|
||||
<url type="homepage">https://jami.net/</url>
|
||||
<url type="bugtracker">https://git.jami.net/savoirfairelinux/jami-client-qt/issues</url>
|
||||
<url type="faq">https://jami.net/help/</url>
|
||||
<url type="help">https://docs.jami.net</url>
|
||||
<url type="donation">https://www.paypal.com/donate/?hosted_button_id=MGUDJLQZ4TP5W</url>
|
||||
<url type="translate">https://www.transifex.com/savoirfairelinux/jami</url>
|
||||
<url type="homepage">https://jami.net/</url>
|
||||
<url type="bugtracker">https://git.jami.net/savoirfairelinux/jami-client-qt/issues</url>
|
||||
<url type="faq">https://docs.jami.net/user/faq.html</url>
|
||||
<url type="help">https://forum.jami.net/</url>
|
||||
<url type="donation">https://jami.net/whydonate/</url>
|
||||
<url type="translate">https://www.transifex.com/savoirfairelinux/jami</url>
|
||||
|
||||
<!-- Maximum caption length is 60 characters -->
|
||||
<!-- Officially GIF is not an allowed video format, but it appears to work nonetheless -->
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<caption>Send Audio, Video and Chat messages</caption>
|
||||
<caption xml:lang="hu">Hang-, video- és csevegőüzeneteket küldhet</caption>
|
||||
<image type="source" width="1310" height="650">https://dl.jami.net/media-resources/screenshots/jami_linux_audiovideo.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Easily share desktop contents</caption>
|
||||
<caption xml:lang="hu">Könnyen megoszthatja az asztali tartalmat</caption>
|
||||
<image type="source" width="1016" height="659">https://dl.jami.net/media-resources/screenshots/jami_linux_screenshare.png</image>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Crystal clear audio calls between Jami users</caption>
|
||||
<caption xml:lang="hu">Kristálytiszta hanghívások a Jami felhasználók között</caption>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/audio-call_web.webm</video>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Conference calls with an unlimited participants</caption>
|
||||
<caption xml:lang="hu">Konferenciahívások korlátlan számú résztvevővel</caption>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/conference_web.webm</video>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Encrypted and secure text messaging, no servers</caption>
|
||||
<caption xml:lang="hu">Titkosított és biztonságos csevegési üzenetküldés, kiszolgálók nélkül</caption>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/chat_web.webm</video>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<caption>Send files of any size</caption>
|
||||
<caption xml:lang="hu">Bármilyen méretű fájl küldése</caption>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/files-share_web.webm</video>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<!-- Maximum caption length is 60 characters -->
|
||||
<!-- Officially GIF is not an allowed video format, but it appears to work nonetheless -->
|
||||
<screenshots>
|
||||
<screenshot type="default">
|
||||
<image type="source" width="1310" height="650">https://dl.jami.net/media-resources/screenshots/jami_linux_audiovideo.png</image>
|
||||
<caption>Send chat messages and talk with audio and video</caption>
|
||||
<caption xml:lang="hu">Csevegőüzenetek küldése, valamint hang- és videobeszélgetés</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<image type="source" width="1016" height="659">https://dl.jami.net/media-resources/screenshots/jami_linux_screenshare.png</image>
|
||||
<caption>Screen sharing</caption>
|
||||
<caption xml:lang="hu">Képernyőmegosztás</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/audio-call_web.webm</video>
|
||||
<caption>Crystal clear audio calls between Jami users</caption>
|
||||
<caption xml:lang="hu">Kristálytiszta hanghívások a Jami felhasználók között</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/conference_web.webm</video>
|
||||
<caption>Conference calls with an unlimited number of participants</caption>
|
||||
<caption xml:lang="hu">Konferenciahívások korlátlan számú résztvevővel</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/chat_web.webm</video>
|
||||
<caption>Encrypted and secure text messaging without servers</caption>
|
||||
<caption xml:lang="hu">Titkosított és biztonságos csevegési üzenetküldés, kiszolgálók nélkül</caption>
|
||||
</screenshot>
|
||||
<screenshot>
|
||||
<video container="webm" codec="vp9" width="600" height="400">https://dl.jami.net/media-resources/gifs_features/conversiongif_webm/files-share_web.webm</video>
|
||||
<caption>Transfer files of any size</caption>
|
||||
<caption xml:lang="hu">Bármilyen méretű fájl küldése</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
|
||||
<launchable type="desktop-id">jami.desktop</launchable>
|
||||
<launchable type="desktop-id">jami.desktop</launchable>
|
||||
|
||||
<provides><binary>jami</binary></provides>
|
||||
<provides><binary>jami</binary></provides>
|
||||
|
||||
<!-- https://specifications.freedesktop.org/menu-spec/latest/apa.html -->
|
||||
<!-- https://specifications.freedesktop.org/menu-spec/latest/apas02.html -->
|
||||
<categories>
|
||||
<category>Chat</category>
|
||||
<category>Communication</category>
|
||||
<category>FileTransfer</category>
|
||||
<category>InstantMessaging</category>
|
||||
<category>Network</category>
|
||||
<category>P2P</category>
|
||||
<category>Productivity</category>
|
||||
</categories>
|
||||
<!-- https://specifications.freedesktop.org/menu-spec/latest/apa.html -->
|
||||
<!-- https://specifications.freedesktop.org/menu-spec/latest/apas02.html -->
|
||||
<categories>
|
||||
<category>Chat</category>
|
||||
<category>Communication</category>
|
||||
<category>FileTransfer</category>
|
||||
<category>InstantMessaging</category>
|
||||
<category>Network</category>
|
||||
<category>P2P</category>
|
||||
<category>Productivity</category>
|
||||
</categories>
|
||||
|
||||
<translation type="gettext">jami-client-qt</translation>
|
||||
<translation type="gettext">jami-client-qt</translation>
|
||||
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
<content_attribute id="social-audio">intense</content_attribute>
|
||||
</content_rating>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
<content_attribute id="social-audio">intense</content_attribute>
|
||||
</content_rating>
|
||||
|
||||
<requires><id>net.jami.daemon</id></requires>
|
||||
<requires><id>net.jami.daemon</id></requires>
|
||||
|
||||
</component>
|
||||
|
||||
@ -49,7 +49,7 @@ QT_MAJOR := 6
|
||||
QT_MINOR := 6
|
||||
QT_PATCH := 1
|
||||
QT_TARBALL_CHECKSUM := dd3668f65645fe270bc615d748bd4dc048bd17b9dc297025106e6ecc419ab95d
|
||||
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
|
||||
|
||||
@ -166,13 +166,14 @@ DISTRIBUTIONS := \
|
||||
debian_unstable \
|
||||
ubuntu_20.04 \
|
||||
ubuntu_22.04 \
|
||||
ubuntu_23.04 \
|
||||
ubuntu_23.10 \
|
||||
ubuntu_24.04 \
|
||||
ubuntu_24.10 \
|
||||
fedora_37 \
|
||||
fedora_38 \
|
||||
fedora_39 \
|
||||
fedora_40 \
|
||||
fedora_41 \
|
||||
alma_9 \
|
||||
opensuse-leap_15.4 \
|
||||
opensuse-leap_15.5 \
|
||||
|
||||
@ -27,9 +27,7 @@ RUN /opt/prebuild-package-debian.sh qt-deps
|
||||
COPY extras/packaging/gnu-linux/rules/debian/control /tmp/builddeps/debian/control
|
||||
RUN /opt/prebuild-package-debian.sh jami-deps
|
||||
|
||||
# Install CMake 3.21 for Qt 6
|
||||
ADD extras/packaging/gnu-linux/scripts/install-cmake.sh /opt/install-cmake.sh
|
||||
RUN /opt/install-cmake.sh
|
||||
RUN apt-get remove -y libre2-dev libre2-11
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
CMD ["/opt/build-package-debian.sh"]
|
||||
|
||||
@ -27,9 +27,7 @@ RUN /opt/prebuild-package-debian.sh qt-deps
|
||||
COPY extras/packaging/gnu-linux/rules/debian/control /tmp/builddeps/debian/control
|
||||
RUN /opt/prebuild-package-debian.sh jami-deps
|
||||
|
||||
# Install CMake 3.21 for Qt 6
|
||||
ADD extras/packaging/gnu-linux/scripts/install-cmake.sh /opt/install-cmake.sh
|
||||
RUN /opt/install-cmake.sh
|
||||
RUN apt-get remove -y libre2-dev libre2-11
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
CMD ["/opt/build-package-debian.sh"]
|
||||
|
||||
103
extras/packaging/gnu-linux/docker/Dockerfile_fedora_41
Normal file
103
extras/packaging/gnu-linux/docker/Dockerfile_fedora_41
Normal file
@ -0,0 +1,103 @@
|
||||
FROM fedora:41
|
||||
|
||||
RUN dnf clean all
|
||||
RUN dnf update -y
|
||||
|
||||
RUN dnf install -y dnf-command\(builddep\) rpmdevtools && \
|
||||
dnf install -y mock
|
||||
|
||||
RUN dnf group install -y x-software-development
|
||||
|
||||
RUN dnf install -y \
|
||||
git \
|
||||
rpm-build \
|
||||
tar \
|
||||
make \
|
||||
autoconf \
|
||||
automake \
|
||||
nasm \
|
||||
speexdsp-devel \
|
||||
pulseaudio-libs-devel \
|
||||
libcanberra-devel \
|
||||
libcurl-devel \
|
||||
libtool \
|
||||
mesa-libgbm-devel \
|
||||
mesa-dri-drivers \
|
||||
dbus-devel \
|
||||
expat-devel \
|
||||
pcre-devel \
|
||||
yaml-cpp-devel \
|
||||
libXext-devel \
|
||||
libXfixes-devel \
|
||||
yasm \
|
||||
speex-devel \
|
||||
gsm-devel \
|
||||
chrpath \
|
||||
check \
|
||||
astyle \
|
||||
uuid-c++-devel \
|
||||
gettext-devel \
|
||||
gcc-c++ \
|
||||
which \
|
||||
alsa-lib-devel \
|
||||
systemd-devel \
|
||||
libuuid-devel \
|
||||
uuid-devel \
|
||||
gnutls-devel \
|
||||
nettle-devel \
|
||||
opus-devel \
|
||||
patch \
|
||||
jsoncpp-devel \
|
||||
libnatpmp-devel \
|
||||
webkitgtk4-devel \
|
||||
cryptopp-devel \
|
||||
libva-devel \
|
||||
libvdpau-devel \
|
||||
msgpack-devel \
|
||||
NetworkManager-libnm-devel \
|
||||
openssl-devel \
|
||||
clutter-devel \
|
||||
clutter-gtk-devel \
|
||||
libappindicator-gtk3-devel \
|
||||
libnotify-devel \
|
||||
libupnp-devel \
|
||||
qrencode-devel \
|
||||
libargon2-devel \
|
||||
libsndfile-devel \
|
||||
libdrm \
|
||||
gperf \
|
||||
bison \
|
||||
clang18-devel \
|
||||
llvm18-devel \
|
||||
nodejs \
|
||||
flex \
|
||||
gstreamer1 gstreamer1-devel \
|
||||
gstreamer1-plugins-base-devel \
|
||||
gstreamer1-plugins-good \
|
||||
gstreamer1-plugins-bad-free-devel \
|
||||
nss-devel \
|
||||
libxcb* \
|
||||
libxkb* \
|
||||
libX11-devel \
|
||||
vulkan-devel \
|
||||
libXrender-devel \
|
||||
xcb-util-* \
|
||||
xz \
|
||||
xkeyboard-config \
|
||||
libnotify \
|
||||
wget \
|
||||
libstdc++-static \
|
||||
sqlite-devel \
|
||||
perl-generators \
|
||||
perl-English \
|
||||
libxshmfence-devel \
|
||||
ninja-build \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
python3.10 \
|
||||
cups-devel \
|
||||
pipewire-devel
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
|
||||
|
||||
CMD ["/opt/build-package-rpm.sh"]
|
||||
@ -1,6 +1,6 @@
|
||||
FROM opensuse/leap:15.5
|
||||
|
||||
RUN zypper refresh
|
||||
RUN zypper --gpg-auto-import-keys refresh
|
||||
|
||||
RUN zypper --non-interactive install -y \
|
||||
dnf \
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:23.04
|
||||
FROM ubuntu:24.10
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
@ -18,5 +18,12 @@ RUN /opt/prebuild-package-debian.sh qt-deps
|
||||
COPY extras/packaging/gnu-linux/rules/debian/control /tmp/builddeps/debian/control
|
||||
RUN /opt/prebuild-package-debian.sh jami-deps
|
||||
|
||||
# Remove the libre2-dev package in order to force Qt to build using the bundled
|
||||
# version of the RE2 library. This is necessary because the system version of the
|
||||
# library on Ubuntu 24.10 (libre2-11) is not compatible with the one used in
|
||||
# Qt 6.6.1 due to an API change:
|
||||
# https://codereview.qt-project.org/c/qt/qtwebengine/+/516094
|
||||
RUN apt-get remove -y libre2-dev libre2-11
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
CMD ["/opt/build-package-debian.sh"]
|
||||
@ -1,10 +1,18 @@
|
||||
From deeacfdb5a6d1d300d4ba991df76aa12e5dbaa42 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
|
||||
<sebastien.blin@savoirfairelinux.com>
|
||||
Date: Tue, 16 Apr 2024 09:54:32 -0400
|
||||
Subject: [PATCH] fix imp->importlib
|
||||
From 24fb774485f719df1e84dda31605d3f69202d69f Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Thu, 8 Aug 2024 14:59:17 -0400
|
||||
Subject: [PATCH] qtwebengine: enable building with Python 3.12
|
||||
|
||||
Replace the deprecated imp module by importlib:
|
||||
https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/524014
|
||||
https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/534568
|
||||
|
||||
Update six to fix html5lib import failure:
|
||||
https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/535605
|
||||
https://issues.chromium.org/issues/40286977
|
||||
---
|
||||
.../protobufs/binary_proto_generator.py | 8 ++++++--
|
||||
.../mojo/public/tools/mojom/mojom/fileutil.py | 1 -
|
||||
.../tools/mojom/mojom/fileutil_unittest.py | 5 +----
|
||||
.../mojom/mojom/generate/generator_unittest.py | 7 ++-----
|
||||
@ -14,11 +22,37 @@ Subject: [PATCH] fix imp->importlib
|
||||
.../mojo/public/tools/mojom/mojom/parse/lexer.py | 1 -
|
||||
.../tools/mojom/mojom/parse/lexer_unittest.py | 7 ++-----
|
||||
.../tools/mojom/mojom/parse/parser_unittest.py | 5 -----
|
||||
.../3rdparty/chromium/third_party/six/src/six.py | 16 ++++++++++++++++
|
||||
10 files changed, 23 insertions(+), 37 deletions(-)
|
||||
.../third_party/catapult/third_party/six/six.py | 16 ++++++++++++++++
|
||||
11 files changed, 29 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
index 2a1802dccdc..8b9de65ed0b 100755
|
||||
--- a/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/components/resources/protobufs/binary_proto_generator.py
|
||||
@@ -9,7 +9,7 @@
|
||||
"""
|
||||
from __future__ import print_function
|
||||
import abc
|
||||
-import imp
|
||||
+from importlib import util as imp_util
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
@@ -68,7 +68,11 @@ class GoogleProtobufModuleImporter:
|
||||
raise ImportError(fullname)
|
||||
|
||||
filepath = self._fullname_to_filepath(fullname)
|
||||
- return imp.load_source(fullname, filepath)
|
||||
+ spec = imp_util.spec_from_file_location(fullname, filepath)
|
||||
+ loaded = imp_util.module_from_spec(spec)
|
||||
+ spec.loader.exec_module(loaded)
|
||||
+
|
||||
+ return loaded
|
||||
|
||||
class BinaryProtoGenerator:
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
index 29daec367c..124f12c134 100644
|
||||
index 29daec367c5..124f12c134b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil.py
|
||||
@@ -3,7 +3,6 @@
|
||||
@ -30,7 +64,7 @@ index 29daec367c..124f12c134 100644
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
index 48eaf4eca9..c93d22898d 100644
|
||||
index 48eaf4eca94..c93d22898d2 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/fileutil_unittest.py
|
||||
@@ -2,19 +2,16 @@
|
||||
@ -55,7 +89,7 @@ index 48eaf4eca9..c93d22898d 100644
|
||||
temp_dir = tempfile.mkdtemp()
|
||||
try:
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
index 76cda3981f..7143e07c4d 100644
|
||||
index 76cda3981f3..7143e07c4d7 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/generator_unittest.py
|
||||
@@ -2,12 +2,11 @@
|
||||
@ -94,7 +128,7 @@ index 76cda3981f..7143e07c4d 100644
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
index 4259374513..558e71e119 100644
|
||||
index 4259374513f..558e71e1193 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/generate/translate_unittest.py
|
||||
@@ -2,16 +2,12 @@
|
||||
@ -115,7 +149,7 @@ index 4259374513..558e71e119 100644
|
||||
"""Tests |parser.Parse()|."""
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
index c36376712e..b289f7b11f 100644
|
||||
index c36376712e7..b289f7b11f6 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/ast_unittest.py
|
||||
@@ -2,14 +2,10 @@
|
||||
@ -148,7 +182,7 @@ index c36376712e..b289f7b11f 100644
|
||||
"""Tests various AST classes."""
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
index 5fc582025e..2fa5d2be6a 100644
|
||||
index 5fc582025ee..2fa5d2be6ab 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/conditional_features_unittest.py
|
||||
@@ -2,12 +2,11 @@
|
||||
@ -192,7 +226,7 @@ index 5fc582025e..2fa5d2be6a 100644
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
index 73ca15df94..1083a1af7b 100644
|
||||
index 73ca15df94c..1083a1af7bb 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer.py
|
||||
@@ -2,7 +2,6 @@
|
||||
@ -204,7 +238,7 @@ index 73ca15df94..1083a1af7b 100644
|
||||
import sys
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
index ce376da66e..bc9f835431 100644
|
||||
index ce376da66e0..bc9f8354316 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/lexer_unittest.py
|
||||
@@ -2,12 +2,11 @@
|
||||
@ -241,7 +275,7 @@ index ce376da66e..bc9f835431 100644
|
||||
# we'll do it anyway. (I'm pretty sure ply's lexer never cares about comparing
|
||||
# for object identity.)
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
index 0513343ec7..0a26307b1a 100644
|
||||
index 0513343ec7e..0a26307b1a3 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/mojo/public/tools/mojom/mojom/parse/parser_unittest.py
|
||||
@@ -2,16 +2,12 @@
|
||||
@ -268,10 +302,10 @@ index 0513343ec7..0a26307b1a 100644
|
||||
-
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/six/src/six.py b/qtwebengine/src/3rdparty/chromium/third_party/six/src/six.py
|
||||
index 5fe9f8e141..96b06f8ce7 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/six/src/six.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/six/src/six.py
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/catapult/third_party/six/six.py b/qtwebengine/src/3rdparty/chromium/third_party/catapult/third_party/six/six.py
|
||||
index 83f69783d1a..5e7f0ce4437 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/catapult/third_party/six/six.py
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/catapult/third_party/six/six.py
|
||||
@@ -71,6 +71,11 @@ else:
|
||||
MAXSIZE = int((1 << 63) - 1)
|
||||
del X
|
||||
@ -310,5 +344,5 @@ index 5fe9f8e141..96b06f8ce7 100644
|
||||
|
||||
|
||||
--
|
||||
2.43.0
|
||||
2.34.1
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From cf208d11dc8a9a02160a57283596ec8bab964a09 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
Date: Mon, 27 May 2024 16:01:21 -0400
|
||||
Subject: [PATCH] qtwayland: downgrade wl-seat to avoid high-resolution
|
||||
scrolling events
|
||||
|
||||
---
|
||||
qtwayland/src/client/qwaylandinputdevice.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qtwayland/src/client/qwaylandinputdevice.cpp b/qtwayland/src/client/qwaylandinputdevice.cpp
|
||||
index a4f8757e3c..ad0aa7941c 100644
|
||||
--- a/qtwayland/src/client/qwaylandinputdevice.cpp
|
||||
+++ b/qtwayland/src/client/qwaylandinputdevice.cpp
|
||||
@@ -383,7 +383,7 @@ QWaylandInputDevice::Touch::~Touch()
|
||||
}
|
||||
|
||||
QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version, uint32_t id)
|
||||
- : QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 9))
|
||||
+ : QtWayland::wl_seat(display->wl_registry(), id, qMin(version, 7))
|
||||
, mQDisplay(display)
|
||||
, mDisplay(display->wl_display())
|
||||
{
|
||||
--
|
||||
2.45.0
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 420b3e5ac2e91b7a99488ac34577e2798a84a68c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Tue, 6 Aug 2024 17:35:56 -0400
|
||||
Subject: [PATCH] qtbase: fix CMake error
|
||||
|
||||
For more information, see:
|
||||
https://github.com/qt/qtbase/commit/3411f2984a5325a35e3bed1f961e5973d8a565b9
|
||||
---
|
||||
qtbase/configure.cmake | 1 +
|
||||
qtbase/src/corelib/CMakeLists.txt | 1 -
|
||||
2 files changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qtbase/configure.cmake b/qtbase/configure.cmake
|
||||
index 43de2aa026..37a82dcdb6 100644
|
||||
--- a/qtbase/configure.cmake
|
||||
+++ b/qtbase/configure.cmake
|
||||
@@ -18,6 +18,7 @@ if(TARGET ZLIB::ZLIB)
|
||||
set_property(TARGET ZLIB::ZLIB PROPERTY IMPORTED_GLOBAL TRUE)
|
||||
endif()
|
||||
|
||||
+qt_find_package(Threads PROVIDED_TARGETS Threads::Threads)
|
||||
qt_find_package(WrapOpenSSLHeaders PROVIDED_TARGETS WrapOpenSSLHeaders::WrapOpenSSLHeaders MODULE_NAME core)
|
||||
# openssl_headers
|
||||
# OPENSSL_VERSION_MAJOR is not defined for OpenSSL 1.1.1
|
||||
diff --git a/qtbase/src/corelib/CMakeLists.txt b/qtbase/src/corelib/CMakeLists.txt
|
||||
index 31b81734e8..b62e2f763b 100644
|
||||
--- a/qtbase/src/corelib/CMakeLists.txt
|
||||
+++ b/qtbase/src/corelib/CMakeLists.txt
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright (C) 2022 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
-qt_find_package(Threads PROVIDED_TARGETS Threads::Threads)
|
||||
qt_find_package(WrapPCRE2 PROVIDED_TARGETS WrapPCRE2::WrapPCRE2)
|
||||
qt_find_package(WrapZLIB PROVIDED_TARGETS WrapZLIB::WrapZLIB)
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 4c7360faeb0fb7f1dfd995619fb8c596b4e15606 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Thu, 8 Aug 2024 10:29:43 -0400
|
||||
Subject: [PATCH] qtwebengine: add missing chromium dependencies
|
||||
|
||||
For more information, see:
|
||||
https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/555586
|
||||
---
|
||||
chromium/content/public/browser/BUILD.gn | 1 +
|
||||
chromium/extensions/browser/api/declarative_net_request/BUILD.gn | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn b/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
index b25bf5764e7..dfbfb2ec77b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
@@ -515,6 +515,7 @@ jumbo_source_set("browser_sources") {
|
||||
"//cc",
|
||||
"//components/services/storage/public/cpp",
|
||||
"//components/viz/host",
|
||||
+ "//components/spellcheck:buildflags",
|
||||
"//content/browser", # Must not be public_deps!
|
||||
"//device/fido",
|
||||
"//gpu",
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn b/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
index 1fc492f5a0c..13a266e22f1 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
@@ -23,6 +23,7 @@ source_set("declarative_net_request") {
|
||||
"//extensions/common",
|
||||
"//extensions/common/api",
|
||||
"//services/preferences/public/cpp",
|
||||
+ "//components/web_cache/browser",
|
||||
]
|
||||
|
||||
public_deps = [ "//extensions/browser:browser_sources" ]
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@ -0,0 +1,49 @@
|
||||
From ab6d5bebaf68a9f4d00440b2adbaffe0e5b2ae6c Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Thu, 8 Aug 2024 10:55:08 -0400
|
||||
Subject: [PATCH] qtwebengine: fix libxml2 build error
|
||||
|
||||
Version 2.12 of libxml2 introduced a change that broke chromium's build,
|
||||
see: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523633
|
||||
---
|
||||
.../third_party/blink/renderer/core/xml/xslt_processor.h | 5 +++++
|
||||
.../blink/renderer/core/xml/xslt_processor_libxslt.cc | 4 ++++
|
||||
2 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor.h b/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
|
||||
index d53835e9675..72536e4fd7d 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor.h
|
||||
@@ -77,7 +77,12 @@ class XSLTProcessor final : public ScriptWrappable {
|
||||
|
||||
void reset();
|
||||
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+ static void ParseErrorFunc(void* user_data, const xmlError*);
|
||||
+#else
|
||||
static void ParseErrorFunc(void* user_data, xmlError*);
|
||||
+#endif
|
||||
+
|
||||
static void GenericErrorFunc(void* user_data, const char* msg, ...);
|
||||
|
||||
// Only for libXSLT callbacks
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc b/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
|
||||
index 133e0b3355d..e8e6a09f485 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/third_party/blink/renderer/core/xml/xslt_processor_libxslt.cc
|
||||
@@ -66,7 +66,11 @@ void XSLTProcessor::GenericErrorFunc(void*, const char*, ...) {
|
||||
// It would be nice to do something with this error message.
|
||||
}
|
||||
|
||||
+#if LIBXML_VERSION >= 21200
|
||||
+void XSLTProcessor::ParseErrorFunc(void* user_data, const xmlError* error) {
|
||||
+#else
|
||||
void XSLTProcessor::ParseErrorFunc(void* user_data, xmlError* error) {
|
||||
+#endif
|
||||
FrameConsole* console = static_cast<FrameConsole*>(user_data);
|
||||
if (!console)
|
||||
return;
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
From 6e0848a1c51c6494e3b7410c5fe38941d48fcb36 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Wed, 16 Oct 2024 22:32:12 -0400
|
||||
Subject: [PATCH] qtwebengine: fix v8 build error
|
||||
|
||||
In file included from ../../../3rdparty/chromium/v8/src/heap/cppgc/sweeper.h:14,
|
||||
from ./../../../3rdparty/chromium/v8/src/heap/cppgc/sweeper.cc:5,
|
||||
from gen/v8/cppgc_base_jumbo_7.cc:5:
|
||||
../../../3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h: In member function 'void cppgc::internal::StatsCollector::ForAllAllocationObservers(Callback)':
|
||||
../../../3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h:401:48: error: cannot convert 'std::vector<cppgc::internal::StatsCollector::AllocationObserver*>::iterator' to 'const char*'
|
||||
401 | std::remove(allocation_observers_.begin(), allocation_observers_.end(),
|
||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
|
||||
| |
|
||||
| std::vector<cppgc::internal::StatsCollector::AllocationObserver*>::iterator
|
||||
---
|
||||
.../src/3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h b/qtwebengine/src/3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h
|
||||
index 2cf728489d..d8414ae3c6 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/v8/src/heap/cppgc/stats-collector.h
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
+#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <vector>
|
||||
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -1,2 +1,7 @@
|
||||
0001-replace_imp_by_importlib.patch
|
||||
0002-fix-binary-tokenizer.patch
|
||||
0001-qtwebengine-enable-building-with-Python-3.12.patch
|
||||
0002-fix-binary-tokenizer.patch
|
||||
0003-qtwayland-downgrade-wl-seat-to-avoid-high-resolution.patch
|
||||
0004-qtbase-fix-CMake-error.patch
|
||||
0005-qtwebengine-add-missing-chromium-dependencies.patch
|
||||
0006-qtwebengine-fix-libxml2-build-error.patch
|
||||
0007-qtwebengine-fix-v8-build-error.patch
|
||||
@ -22,7 +22,7 @@ Build-Depends: debhelper (>= 9),
|
||||
libpulse-dev,
|
||||
libasound2-dev,
|
||||
libexpat1-dev,
|
||||
libpcre3-dev,
|
||||
libpcre3-dev | libpcre2-dev,
|
||||
libyaml-cpp-dev,
|
||||
libboost-dev,
|
||||
libxext-dev,
|
||||
|
||||
@ -99,12 +99,12 @@ if [ -f /etc/os-release ]; then
|
||||
ENDTAG="ubuntu_20.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "jammy" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_22.04" ]; then
|
||||
ENDTAG="ubuntu_22.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "lunar" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.04" ]; then
|
||||
ENDTAG="ubuntu_23.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "mantic" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_23.10" ]; then
|
||||
ENDTAG="ubuntu_23.10"
|
||||
elif [ "${UBUNTU_CODENAME}" = "noble" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_24.04" ]; then
|
||||
ENDTAG="ubuntu_24.04"
|
||||
elif [ "${UBUNTU_CODENAME}" = "oracular" ] || [ "${ID}_${VERSION_ID}" = "ubuntu_24.10" ]; then
|
||||
ENDTAG="ubuntu_24.10"
|
||||
elif [ "${ID}" = "debian" ] && \
|
||||
[ "$(command -v lsb_release)" ] && \
|
||||
[ "$(lsb_release -rs)" = "testing" ]; then
|
||||
|
||||
@ -30,6 +30,7 @@ Vendor: Savoir-faire Linux Inc.
|
||||
URL: https://jami.net/
|
||||
Source: jami-libqt-%{version}.tar.xz
|
||||
Patch0: 0001-fix-gcc14.patch
|
||||
Patch1: 0002-qtwebengine-add-missing-chromium-dependencies.patch
|
||||
|
||||
%global gst 0.10
|
||||
%if 0%{?fedora} || 0%{?rhel} > 7
|
||||
@ -65,7 +66,8 @@ This package contains Qt libraries for Jami.
|
||||
|
||||
%prep
|
||||
%setup -n qt-everywhere-src-%{version}
|
||||
%patch0 -p1
|
||||
%patch -P 0 -p1
|
||||
%patch -P 1 -p1
|
||||
|
||||
%build
|
||||
echo "Building Qt using %{job_count} parallel jobs"
|
||||
|
||||
@ -0,0 +1,40 @@
|
||||
From 04778c7f54c8a1a0e7fced75c5ef39ced82cece1 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Fran=C3=A7ois-Simon=20Fauteux-Chapleau?=
|
||||
<francois-simon.fauteux-chapleau@savoirfairelinux.com>
|
||||
Date: Sat, 12 Oct 2024 16:21:35 -0400
|
||||
Subject: [PATCH] qtwebengine: add missing chromium dependencies
|
||||
|
||||
For more information, see:
|
||||
https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/555586
|
||||
---
|
||||
chromium/content/public/browser/BUILD.gn | 1 +
|
||||
chromium/extensions/browser/api/declarative_net_request/BUILD.gn | 1 +
|
||||
2 files changed, 2 insertions(+)
|
||||
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn b/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
index b25bf5764e7..dfbfb2ec77b 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/content/public/browser/BUILD.gn
|
||||
@@ -515,6 +515,7 @@ jumbo_source_set("browser_sources") {
|
||||
"//cc",
|
||||
"//components/services/storage/public/cpp",
|
||||
"//components/viz/host",
|
||||
+ "//components/spellcheck:buildflags",
|
||||
"//content/browser", # Must not be public_deps!
|
||||
"//device/fido",
|
||||
"//gpu",
|
||||
diff --git a/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn b/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
index 1fc492f5a0c..13a266e22f1 100644
|
||||
--- a/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
+++ b/qtwebengine/src/3rdparty/chromium/extensions/browser/api/declarative_net_request/BUILD.gn
|
||||
@@ -23,6 +23,7 @@ source_set("declarative_net_request") {
|
||||
"//extensions/common",
|
||||
"//extensions/common/api",
|
||||
"//services/preferences/public/cpp",
|
||||
+ "//components/web_cache/browser",
|
||||
]
|
||||
|
||||
public_deps = [ "//extensions/browser:browser_sources" ]
|
||||
--
|
||||
2.47.0
|
||||
|
||||
@ -172,7 +172,7 @@ package-repositories:
|
||||
components: [main]
|
||||
suites: [jami]
|
||||
key-id: A295D773307D25A33AE72F2F64CD5FA175348F84
|
||||
url: https://dl.jami.net/nightly/ubuntu_20.04/
|
||||
url: https://dl.jami.net/internal/ubuntu_20.04/
|
||||
|
||||
parts:
|
||||
desktop-launch:
|
||||
@ -325,6 +325,12 @@ parts:
|
||||
- libgnutls28-dev # TLS
|
||||
- gnutls-bin
|
||||
- libssl-dev
|
||||
- git # PipeWire build dependencies
|
||||
- libasound2-dev #
|
||||
- libdbus-1-dev # These packages are needed by the
|
||||
- libglib2.0-dev # install-pipewire-from-source.sh
|
||||
- ninja-build # script in order to build PipeWire
|
||||
- pkg-config # from source.
|
||||
stage-packages:
|
||||
- libgnutls30
|
||||
- libavutil56
|
||||
|
||||
@ -114,6 +114,8 @@ if [ ! -f "${RPM_PATH}" ]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc39.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_40" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc40.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_41" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc41.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "alma_9" ]]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.el9.x86_64.rpm "${RPM_PATH}"
|
||||
else
|
||||
|
||||
@ -8,9 +8,6 @@ set -e
|
||||
OLD_WD=$(pwd)
|
||||
cd /tmp
|
||||
|
||||
# Install PipeWire's build dependencies
|
||||
apt-get install --yes gcc git libasound2-dev libdbus-1-dev libglib2.0-dev ninja-build pkg-config
|
||||
|
||||
# Get a version of Meson that's recent enough to build PipeWire 1.0.5 (the one available via apt is too old)
|
||||
wget -q https://github.com/mesonbuild/meson/releases/download/0.61.1/meson-0.61.1.tar.gz
|
||||
echo "feb2cefb325b437dbf36146df7c6b87688ddff0b0205caa31dc64055c6da410c meson-0.61.1.tar.gz" | sha256sum --check
|
||||
|
||||
@ -99,6 +99,12 @@ for ARCH in "${ARCHS[@]}"; do
|
||||
echo "$ARCH"
|
||||
cd "$DAEMON"
|
||||
HOST="${ARCH}-apple-darwin"
|
||||
SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
|
||||
|
||||
CC="xcrun -sdk macosx clang"
|
||||
CXX="xcrun -sdk macosx clang++"
|
||||
CFLAGS="-arch $ARCH -isysroot $SDKROOT"
|
||||
CXXFLAGS="-std=c++17 $CFLAGS"
|
||||
CONFIGURE_FLAGS=" --without-dbus --host=${HOST} -with-contrib=$DAEMON/contrib/${ARCH}-apple-darwin${OS_VER} --prefix=${INSTALL}/daemon/$ARCH"
|
||||
|
||||
if [ "${debug}" = "true" ]; then
|
||||
@ -113,7 +119,11 @@ for ARCH in "${ARCHS[@]}"; do
|
||||
mkdir -p "build-macos-${ARCH}"
|
||||
cd "build-macos-${ARCH}"
|
||||
|
||||
"$DAEMON"/configure $CONFIGURE_FLAGS ARCH="$ARCH" || exit 1
|
||||
"$DAEMON"/configure $CONFIGURE_FLAGS ARCH="$ARCH" \
|
||||
CC="$CC $CFLAGS" \
|
||||
CXX="$CXX $CXXFLAGS" \
|
||||
CFLAGS="$CFLAGS" \
|
||||
CXXFLAGS="$CXXFLAGS" || exit 1
|
||||
|
||||
echo "$CONFIGURE_FLAGS"
|
||||
|
||||
|
||||
@ -1 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M42 13.85V39q0 1.2-.9 2.1-.9.9-2.1.9H9q-1.2 0-2.1-.9Q6 40.2 6 39V9q0-1.2.9-2.1Q7.8 6 9 6h25.15Zm-3 1.35L32.8 9H9v30h30ZM24 35.75q2.15 0 3.675-1.525T29.2 30.55q0-2.15-1.525-3.675T24 25.35q-2.15 0-3.675 1.525T18.8 30.55q0 2.15 1.525 3.675T24 35.75ZM11.65 18.8h17.9v-7.15h-17.9ZM9 15.2V39 9Z"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="48px" viewBox="0 -960 960 960" width="48px" fill="#e8eaed"><path d="M480-313 287-506l43-43 120 120v-371h60v371l120-120 43 43-193 193ZM220-160q-24 0-42-18t-18-42v-143h60v143h520v-143h60v143q0 24-18 42t-42 18H220Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 369 B After Width: | Height: | Size: 268 B |
11
resources/icons/share_black_24dp.svg
Normal file
11
resources/icons/share_black_24dp.svg
Normal 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="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
|
||||
<path d="M17.1,15.7c-0.8,0-1.5,0.3-2.1,0.8l-5.3-3.3C9.9,12.8,10,12.4,10,12c0-0.4-0.1-0.8-0.3-1.2l5.3-3.3c0.6,0.5,1.3,0.8,2.1,0.8
|
||||
c1.7,0,3.1-1.4,3.1-3.1S18.9,2,17.1,2C15.4,2,14,3.4,14,5.1c0,0.4,0.1,0.8,0.3,1.2L8.9,9.6C8.3,9.1,7.6,8.9,6.9,8.9
|
||||
c-1.7,0-3.1,1.4-3.1,3.1s1.4,3.1,3.1,3.1c0.8,0,1.5-0.3,2.1-0.8l5.3,3.3C14.1,18,14,18.4,14,18.9c0,1.7,1.4,3.1,3.1,3.1
|
||||
c1.7,0,3.1-1.4,3.1-3.1S18.9,15.7,17.1,15.7z M17.1,20.6c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8c1,0,1.8,0.8,1.8,1.8
|
||||
S18.1,20.6,17.1,20.6z M17.1,3.4c1,0,1.8,0.8,1.8,1.8s-0.8,1.8-1.8,1.8c-1,0-1.8-0.8-1.8-1.8S16.2,3.4,17.1,3.4z M6.9,13.8
|
||||
c-1,0-1.8-0.8-1.8-1.8s0.8-1.8,1.8-1.8S8.6,11,8.6,12S7.8,13.8,6.9,13.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1019 B |
@ -1,11 +1,13 @@
|
||||
<h4 align="left"><span style="font-weight:600"> Created by</span></h4>
|
||||
<p>%1</p>
|
||||
<h4 align="left"><span style="font-weight:600">%2</span></h4>
|
||||
<p>Abhishek Ojha<br>
|
||||
Adrien Béraud<br>
|
||||
Albert Babí<br>
|
||||
Alexandre Lision<br>
|
||||
Alexandr Sergheev<br>
|
||||
Alexandre Viau<br>
|
||||
Alexander Lussier-Cullen<br>
|
||||
Alexandr Sergheev<br>
|
||||
Alexandre Eberhardt<br>
|
||||
Alexandre Lision<br>
|
||||
Alexandre Viau<br>
|
||||
Aline Bonnet<br>
|
||||
Aline Gondim Santos<br>
|
||||
Alireza Toghiani<br>
|
||||
@ -18,7 +20,6 @@ Brando Tovar<br>
|
||||
Capucine Berthet<br>
|
||||
Charles-Francis Damedey<br>
|
||||
Cyrille Béraud<br>
|
||||
Dorina Mosku<br>
|
||||
Eden Abitbol<br>
|
||||
Édric Milaret<br>
|
||||
Éloi Bail<br>
|
||||
@ -33,11 +34,16 @@ Guillaume Roguez<br>
|
||||
Hadrien De Sousa<br>
|
||||
Hugo Lefeuvre<br>
|
||||
Julien Grossholtz<br>
|
||||
Julien Robert<br>
|
||||
Kateryna Kostiuk<br>
|
||||
Kessler DuPont-Teevin<br>
|
||||
Léo Banno-Cloutier<br>
|
||||
Léopold Chappuis<br>
|
||||
Liam Courdoson<br>
|
||||
Loïc Siret<br>
|
||||
Louis Maillard<br>
|
||||
Mathéo Joseph<br>
|
||||
Michel Schmit<br>
|
||||
Mingrui Zhang<br>
|
||||
Mohamed Chibani<br>
|
||||
Mohamed Amine Younes Bouacida<br>
|
||||
@ -57,6 +63,7 @@ Rayan Osseiran<br>
|
||||
Romain Bertozzi<br>
|
||||
Saher Azer<br>
|
||||
Sébastien Blin<br>
|
||||
Seva Ivanov<br>
|
||||
Silbino Gonçalves Matado<br>
|
||||
Simon Désaulniers<br>
|
||||
Simon Zeni<br>
|
||||
@ -64,9 +71,21 @@ Stepan Salenikovich<br>
|
||||
Thibault Wittemberg<br>
|
||||
Thomas Ballasi<br>
|
||||
Trevor Tabah<br>
|
||||
Vitalii Nikitchyn<br>
|
||||
Vsevolod Ivanov<br>
|
||||
Xavier Jouslin de Noray<br>
|
||||
Yang Wang<br></p>
|
||||
<h4 align="left"><span style="font-weight:600"> Artwork by</span></h4>
|
||||
Yang Wang<br>
|
||||
</p>
|
||||
<h4 align="left"><span style="font-weight:600"> %3</span></h4>
|
||||
<p>Charlotte Hoffmann<br>
|
||||
Marianne Forget<br></p>
|
||||
<h4 align="left"><span style="font-weight:600"> %4</span></h4>
|
||||
<p>Dorina Mosku<br>
|
||||
Cabrel Tambue<br>
|
||||
Loïc Bogino<br></p>
|
||||
<h4 align="left"><span style="font-weight:600"> %5</span></h4>
|
||||
<p>Anna<br>
|
||||
Elys<br>
|
||||
VeroJeanLuc<br>
|
||||
</p>
|
||||
<p>%6</p>
|
||||
|
||||
@ -145,6 +145,16 @@ ApplicationWindow {
|
||||
LRCInstance.selectConversation(convUid);
|
||||
}
|
||||
}
|
||||
ListElement {
|
||||
label: "Account ID"
|
||||
type: "combobox"
|
||||
getDataModel: () => AccountListModel
|
||||
displayRole: AccountList.Username
|
||||
onIndexChanged: function(model, index) {
|
||||
const accountId = JamiQmlUtils.getModelData(model, index, AccountList.ID);
|
||||
LRCInstance.currentAccountId = accountId;
|
||||
}
|
||||
}
|
||||
ListElement {
|
||||
label: "Force local preview"
|
||||
type: "checkbox"
|
||||
|
||||
@ -85,7 +85,7 @@ ApplicationWindow {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignTop
|
||||
Layout.topMargin: preferredMargin
|
||||
|
||||
text: connectionFailed ? JamiStrings.reconnectWarn : JamiStrings.reconnectTry
|
||||
text: connectionFailed ? JamiStrings.reconnectWarn : JamiStrings.reconnectAttempt
|
||||
font.pointSize: 11
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
@ -362,7 +362,7 @@ ApplicationWindow {
|
||||
|
||||
function onUpdateCheckReplyReceived(ok, found) {
|
||||
if (!ok) {
|
||||
// Show an error dialog describing that we could not successfully check for an update.
|
||||
// Show an error dialog describing that an update check failed.
|
||||
presentUpdateInfoDialog(JamiStrings.updateCheckError);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -145,7 +145,7 @@ QtObject {
|
||||
if (!view.managed)
|
||||
view.presented();
|
||||
}, props)) {
|
||||
print("could not create view:", viewName);
|
||||
print("An error occurred while creating view:", viewName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,7 +184,7 @@ QtObject {
|
||||
} else
|
||||
view = rootView.pop(StackView.Immediate);
|
||||
if (!view) {
|
||||
print("could not pop view:", obj.objectName);
|
||||
print("An error occurred while attempting to pop view:", obj.objectName);
|
||||
resolveStack();
|
||||
return;
|
||||
}
|
||||
@ -194,7 +194,7 @@ QtObject {
|
||||
if (view.managed) {
|
||||
var objectName = view ? view.objectName : obj.objectName;
|
||||
if (!viewManager.destroyView(resources[objectName])) {
|
||||
print("could not destroy view:", objectName);
|
||||
print("An error occurred while attempting to destroy view:", objectName);
|
||||
} else {
|
||||
print("destroyed view:", objectName);
|
||||
}
|
||||
|
||||
@ -29,6 +29,35 @@ AccountListModel::AccountListModel(LRCInstance* instance, QObject* parent)
|
||||
: AbstractListModelBase(parent)
|
||||
{
|
||||
lrcInstance_ = instance;
|
||||
|
||||
// Avoid resetting/redrawing the model when the account status changes.
|
||||
QObject::connect(&lrcInstance_->accountModel(),
|
||||
&AccountModel::accountStatusChanged,
|
||||
this,
|
||||
[&](const QString& accountId) {
|
||||
auto accountList = lrcInstance_->accountModel().getAccountList();
|
||||
auto index = accountList.indexOf(accountId);
|
||||
if (index != -1) {
|
||||
QModelIndex modelIndex = QAbstractListModel::index(index, 0);
|
||||
Q_EMIT dataChanged(modelIndex, modelIndex /*, ALL ROLES */);
|
||||
}
|
||||
});
|
||||
// If there's a reorder, it's reasonable to reset the model for simplicity, instead
|
||||
// of computing the difference. The same goes for accounts being added and removed.
|
||||
// These operations will only occur when the list is hidden, unless dbus is used while
|
||||
// the list is visible.
|
||||
QObject::connect(&lrcInstance_->accountModel(),
|
||||
&AccountModel::accountsReordered,
|
||||
this,
|
||||
&AccountListModel::reset);
|
||||
QObject::connect(&lrcInstance_->accountModel(),
|
||||
&AccountModel::accountAdded,
|
||||
this,
|
||||
&AccountListModel::reset);
|
||||
QObject::connect(&lrcInstance_->accountModel(),
|
||||
&AccountModel::accountRemoved,
|
||||
this,
|
||||
&AccountListModel::reset);
|
||||
}
|
||||
|
||||
int
|
||||
@ -91,6 +120,7 @@ AccountListModel::roleNames() const
|
||||
void
|
||||
AccountListModel::reset()
|
||||
{
|
||||
// Used to invalidate proxy models.
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
@ -57,7 +57,6 @@ Popup {
|
||||
id: container
|
||||
|
||||
property color color: JamiTheme.secondaryBackgroundColor
|
||||
anchors.centerIn: parent
|
||||
leftPadding: popupMargins
|
||||
bottomPadding: action1.visible || action2.visible ? 10 :popupMargins
|
||||
|
||||
|
||||
@ -51,7 +51,7 @@ SBSMessageBase {
|
||||
bubble.border.color: CurrentConversation.color
|
||||
bubble.border.width: root.isActive ? 1.5 : 0
|
||||
bubble.color: JamiTheme.messageInBgColor
|
||||
bubble.opacity: 0.6
|
||||
bubble.opacity: 1
|
||||
|
||||
Connections {
|
||||
target: CurrentConversation
|
||||
@ -113,7 +113,7 @@ SBSMessageBase {
|
||||
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
Text {
|
||||
id: callLabel
|
||||
objectName: "callLabel"
|
||||
|
||||
@ -141,19 +141,19 @@ SBSMessageBase {
|
||||
}
|
||||
|
||||
JoinCallButton {
|
||||
id: joinCallInAudio
|
||||
objectName: "joinCallInAudio"
|
||||
id: joinCallWithAudio
|
||||
objectName: "joinCallWithAudio"
|
||||
Layout.topMargin: 4
|
||||
Layout.bottomMargin: 4
|
||||
|
||||
text: JamiStrings.joinInAudio
|
||||
text: JamiStrings.joinWithAudio
|
||||
onClicked: MessagesAdapter.joinCall(ActionUri, DeviceId, root.confId, true)
|
||||
}
|
||||
|
||||
JoinCallButton {
|
||||
id: joinCallInVideo
|
||||
objectName: "joinCallInVideo"
|
||||
text: JamiStrings.joinInVideo
|
||||
id: joinCallWithVideo
|
||||
objectName: "joinCallWithVideo"
|
||||
text: JamiStrings.joinWithVideo
|
||||
Layout.topMargin: 4
|
||||
Layout.bottomMargin: 4
|
||||
|
||||
|
||||
@ -40,9 +40,18 @@ Loader {
|
||||
property int seq: MsgSeq.single
|
||||
property string author: Author
|
||||
property string body: Body
|
||||
property int transferStatus: Status
|
||||
property var tid: TID
|
||||
property int transferStatus: TransferStatus
|
||||
onTidChanged: {
|
||||
if (tid === "") {
|
||||
sourceComponent = deletedMsgComp
|
||||
}
|
||||
}
|
||||
onTransferStatusChanged: {
|
||||
if (transferStatus === Interaction.Status.TRANSFER_FINISHED) {
|
||||
if (tid === "") {
|
||||
sourceComponent = deletedMsgComp
|
||||
return;
|
||||
} else if (transferStatus === Interaction.TransferStatus.TRANSFER_FINISHED) {
|
||||
mediaInfo = MessagesAdapter.getMediaInfo(root.body);
|
||||
if (Object.keys(mediaInfo).length !== 0 && WITH_WEBENGINE) {
|
||||
sourceComponent = localMediaMsgComp;
|
||||
@ -58,6 +67,54 @@ Loader {
|
||||
Behavior on opacity { NumberAnimation { duration: 100 } }
|
||||
onLoaded: opacity = 1
|
||||
|
||||
Component {
|
||||
id: deletedMsgComp
|
||||
|
||||
SBSMessageBase {
|
||||
id: deletedItem
|
||||
|
||||
isOutgoing: Author === CurrentAccount.uri
|
||||
showTime: root.showTime
|
||||
seq: root.seq
|
||||
author: Author
|
||||
readers: Readers
|
||||
timestamp: root.timestamp
|
||||
formattedTime: root.formattedTime
|
||||
formattedDay: root.formattedTime
|
||||
extraHeight: 0
|
||||
textContentWidth: textEditId.width
|
||||
textContentHeight: textEditId.height
|
||||
innerContent.children: [
|
||||
TextEdit {
|
||||
id: textEditId
|
||||
|
||||
anchors.right: isOutgoing ? parent.right : undefined
|
||||
anchors.rightMargin: isOutgoing ? timeWidth : 0
|
||||
bottomPadding: 6
|
||||
topPadding: 6
|
||||
leftPadding: 10
|
||||
text: UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author) + " " + JamiStrings.deletedMedia ;
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
width: Math.min((2 / 3) * parent.width, implicitWidth + 18, innerContent.width - senderMargin + 18)
|
||||
|
||||
font.pointSize: JamiTheme.smallFontSize
|
||||
font.hintingPreference: Font.PreferNoHinting
|
||||
renderType: Text.NativeRendering
|
||||
textFormat: Text.RichText
|
||||
clip: true
|
||||
readOnly: true
|
||||
color: getBaseColor()
|
||||
opacity: 0.5
|
||||
|
||||
function getBaseColor() {
|
||||
bubble.isDeleted = true
|
||||
return UtilsAdapter.luma(bubble.color) ? "white" : "dark"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: dataTransferMsgComp
|
||||
|
||||
@ -66,7 +123,7 @@ Loader {
|
||||
|
||||
transferId: Id
|
||||
property var transferStats: MessagesAdapter.getTransferStats(transferId, root.transferStatus)
|
||||
property bool canOpen: root.transferStatus === Interaction.Status.TRANSFER_FINISHED || isOutgoing
|
||||
property bool canOpen: root.transferStatus === Interaction.TransferStatus.TRANSFER_FINISHED || isOutgoing
|
||||
property real maxMsgWidth: root.width - senderMargin -
|
||||
2 * hPadding - avatarBlockWidth
|
||||
- buttonsLoader.width - 24 - 6 - 24
|
||||
@ -112,18 +169,18 @@ Loader {
|
||||
|
||||
sourceComponent: {
|
||||
switch (root.transferStatus) {
|
||||
case Interaction.Status.TRANSFER_CREATED:
|
||||
case Interaction.Status.TRANSFER_FINISHED:
|
||||
case Interaction.TransferStatus.TRANSFER_CREATED:
|
||||
case Interaction.TransferStatus.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:
|
||||
case Interaction.Status.TRANSFER_AWAITING_HOST:
|
||||
case Interaction.TransferStatus.TRANSFER_CANCELED:
|
||||
case Interaction.TransferStatus.TRANSFER_ERROR:
|
||||
case Interaction.TransferStatus.TRANSFER_UNJOINABLE_PEER:
|
||||
case Interaction.TransferStatus.TRANSFER_TIMEOUT_EXPIRED:
|
||||
case Interaction.TransferStatus.TRANSFER_AWAITING_HOST:
|
||||
iconSource = JamiResources.download_black_24dp_svg
|
||||
return optionsComp
|
||||
case Interaction.Status.TRANSFER_ONGOING:
|
||||
case Interaction.TransferStatus.TRANSFER_ONGOING:
|
||||
iconSource = JamiResources.close_black_24dp_svg
|
||||
return optionsComp
|
||||
default:
|
||||
@ -158,7 +215,7 @@ Loader {
|
||||
normalColor: JamiTheme.chatviewBgColor
|
||||
imageColor: JamiTheme.chatviewButtonColor
|
||||
onClicked: {
|
||||
if (root.transferStatus === Interaction.Status.TRANSFER_ONGOING) {
|
||||
if (root.transferStatus === Interaction.TransferStatus.TRANSFER_ONGOING) {
|
||||
return MessagesAdapter.cancelFile(transferId)
|
||||
} else {
|
||||
return MessagesAdapter.acceptFile(transferId)
|
||||
@ -191,7 +248,7 @@ Loader {
|
||||
onClicked: function (mouse) {
|
||||
if (canOpen) {
|
||||
dataTransferItem.hoveredLink = UtilsAdapter.urlFromLocalPath(location)
|
||||
Qt.openUrlExternally(new Url(dataTransferItem.hoveredLink))
|
||||
Qt.openUrlExternally(new URL(dataTransferItem.hoveredLink))
|
||||
} else {
|
||||
dataTransferItem.hoveredLink = ""
|
||||
}
|
||||
@ -223,11 +280,11 @@ Loader {
|
||||
: JamiTheme.chatviewTextColorDark
|
||||
}
|
||||
}
|
||||
}
|
||||
,ProgressBar {
|
||||
},
|
||||
ProgressBar {
|
||||
id: progressBar
|
||||
|
||||
visible: root.transferStatus === Interaction.Status.TRANSFER_ONGOING
|
||||
visible: root.transferStatus === Interaction.TransferStatus.TRANSFER_ONGOING
|
||||
height: visible * implicitHeight
|
||||
value: transferStats.progress / transferStats.totalSize
|
||||
width: transferItem.width
|
||||
|
||||
@ -73,7 +73,7 @@ BaseModalDialog {
|
||||
Layout.bottomMargin: 5
|
||||
|
||||
color: JamiTheme.textColor
|
||||
text: JamiStrings.confirmDeleteQuestion
|
||||
text: JamiStrings.confirmDeleteAccount
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
font.kerning: true
|
||||
|
||||
@ -121,10 +121,7 @@ Item {
|
||||
font.pixelSize : text.length > 16 ? JamiTheme.jamiIdSmallFontSize : JamiTheme.bigFontSize
|
||||
property string registeredName: CurrentAccount.registeredName
|
||||
property string infohash: CurrentAccount.uri
|
||||
text: registeredName ? registeredName : infohash
|
||||
onRegisteredNameChanged: {
|
||||
text = registeredName ? registeredName : infohash
|
||||
}
|
||||
text: (btnId.clicked && registeredName) ? registeredName : infohash
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +151,7 @@ Item {
|
||||
JamiIdControlButton {
|
||||
id: btnEdit
|
||||
anchors.leftMargin: JamiTheme.pushButtonMargins
|
||||
visible: CurrentAccount.registeredName === ""
|
||||
visible: CurrentAccount.registeredName === "" && CurrentAccount.enabled
|
||||
imageColor: enabled ? JamiTheme.tintedBlue : JamiTheme.buttonTintedBlack
|
||||
border.color: usernameTextEdit.editMode ? jamiId.contentColor : "transparent"
|
||||
enabled: {
|
||||
@ -231,11 +228,9 @@ Item {
|
||||
toolTipText: JamiStrings.identifierURI
|
||||
onClicked: {
|
||||
if (clicked) {
|
||||
usernameLabel.text = Qt.binding(function() {return CurrentAccount.uri} );
|
||||
usernameTextEdit.staticText = Qt.binding(function() {return CurrentAccount.uri} );
|
||||
btnId.toolTipText = JamiStrings.identifierRegisterName;
|
||||
} else {
|
||||
usernameLabel.text = Qt.binding(function() {return CurrentAccount.registeredName} );
|
||||
usernameTextEdit.staticText = Qt.binding(function() {return CurrentAccount.registeredName} );
|
||||
btnId.toolTipText = JamiStrings.identifierURI;
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ SplitView {
|
||||
// size (4 pixels). This is done to make it easier to grab small scroll-view handles that are
|
||||
// adjacent to the SplitView handle. Note: vertically oriented handles are not offset.
|
||||
readonly property real extraHandleSize: 4
|
||||
readonly property real handleXPosition: !isRTL ? 0 : -extraHandleSize
|
||||
readonly property real handleXPosition: !UtilsAdapter.isRTL ? 0 : -extraHandleSize
|
||||
readonly property real handleSize: handleRoot.defaultSize + extraHandleSize
|
||||
|
||||
x: control.orientation === Qt.Horizontal ? handleXPosition : 0
|
||||
|
||||
@ -164,7 +164,7 @@ BaseModalDialog {
|
||||
appWindow,
|
||||
"commoncomponents/JamiFileDialog.qml",
|
||||
{
|
||||
title: JamiStrings.selectAvatarImage,
|
||||
title: JamiStrings.selectProfilePicture,
|
||||
fileMode: JamiFileDialog.OpenFile,
|
||||
folder: StandardPaths.writableLocation(
|
||||
StandardPaths.PicturesLocation),
|
||||
|
||||
@ -230,6 +230,12 @@ Control {
|
||||
RowLayout {
|
||||
id: msgRowlayout
|
||||
|
||||
HoverHandler {
|
||||
id: parenthandler
|
||||
}
|
||||
|
||||
property bool msgHovered: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || share.hovered || parenthandler.hovered)
|
||||
|
||||
Layout.preferredHeight: {
|
||||
var h = innerContent.height + root.extraHeight;
|
||||
if (emojiReactions.emojis !== "")
|
||||
@ -278,14 +284,10 @@ Control {
|
||||
|
||||
anchors.right: isOutgoing ? bubble.left : undefined
|
||||
anchors.left: !isOutgoing ? bubble.right : undefined
|
||||
width: JamiTheme.emojiPushButtonSize * 2
|
||||
width: JamiTheme.emojiPushButtonSize * 4
|
||||
height: JamiTheme.emojiPushButtonSize
|
||||
anchors.verticalCenter: bubble.verticalCenter
|
||||
|
||||
HoverHandler {
|
||||
id: bgHandler
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: more
|
||||
objectName: "more"
|
||||
@ -299,24 +301,24 @@ Control {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: isOutgoing ? optionButtonItem.right : undefined
|
||||
anchors.left: !isOutgoing ? optionButtonItem.left : undefined
|
||||
visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered)
|
||||
visible: msgRowlayout.msgHovered
|
||||
source: JamiResources.more_vert_24dp_svg
|
||||
width: optionButtonItem.width / 2
|
||||
width: optionButtonItem.width / 4
|
||||
height: optionButtonItem.height
|
||||
circled: false
|
||||
property bool isOpen: false
|
||||
property var obj: undefined
|
||||
|
||||
function bind() {
|
||||
function setBindings() {
|
||||
more.isOpen = false;
|
||||
visible = Qt.binding(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || bgHandler.hovered));
|
||||
visible = Qt.binding(() => msgRowlayout.msgHovered);
|
||||
imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
|
||||
normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (more.isOpen) {
|
||||
more.bind();
|
||||
more.setBindings();
|
||||
obj.close();
|
||||
} else {
|
||||
var component = Qt.createComponent("qrc:/commoncomponents/ShowMoreMenu.qml");
|
||||
@ -332,7 +334,7 @@ Control {
|
||||
});
|
||||
obj.open();
|
||||
more.isOpen = true;
|
||||
visible = true;
|
||||
visible = true; // the button stay visible as long the popup is open even if it's not hovered
|
||||
imageColor = JamiTheme.chatViewFooterImgHoverColor;
|
||||
normalColor = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
@ -348,19 +350,75 @@ Control {
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
toolTipText: JamiStrings.reply
|
||||
source: JamiResources.reply_black_24dp_svg
|
||||
width: optionButtonItem.width / 2
|
||||
width: optionButtonItem.width / 4
|
||||
height: optionButtonItem.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.rightMargin: 5
|
||||
anchors.right: isOutgoing ? more.left : undefined
|
||||
anchors.left: !isOutgoing ? more.right : undefined
|
||||
visible: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || bgHandler.hovered)
|
||||
visible: msgRowlayout.msgHovered
|
||||
|
||||
onClicked: {
|
||||
MessagesAdapter.editId = "";
|
||||
MessagesAdapter.replyToId = Id;
|
||||
}
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: share
|
||||
objectName: "share"
|
||||
|
||||
circled: false
|
||||
imageColor: hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
toolTipText: JamiStrings.share
|
||||
source: JamiResources.share_black_24dp_svg
|
||||
|
||||
width: optionButtonItem.width / 4
|
||||
height: optionButtonItem.height
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.rightMargin: 5
|
||||
anchors.right: isOutgoing ? reply.left : undefined
|
||||
anchors.left: !isOutgoing ? reply.right : undefined
|
||||
visible: msgRowlayout.msgHovered
|
||||
property bool isOpen: false
|
||||
property var obj: undefined
|
||||
|
||||
function setBindings() { // when the popup is closed, setBindings is called to reset the icon's visual settings
|
||||
share.isOpen = false;
|
||||
visible = Qt.binding(() => msgRowlayout.msgHovered);
|
||||
imageColor = Qt.binding(() => hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor);
|
||||
normalColor = Qt.binding(() => JamiTheme.primaryBackgroundColor);
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
if (share.isOpen) {
|
||||
share.setBindings();
|
||||
obj.close();
|
||||
} else {
|
||||
if (root.type === 2 || root.type === 5) {
|
||||
// 2=TEXT and 5=DATA_TRANSFER (any kind of file) defined in interaction.h
|
||||
var component = Qt.createComponent("qrc:/commoncomponents/ShareMessageMenu.qml");
|
||||
obj = component.createObject(share, {
|
||||
"isOutgoing": isOutgoing,
|
||||
"msgId": Id,
|
||||
"msgBody": Body,
|
||||
"type": root.type,
|
||||
"transferName": TransferName,
|
||||
"msgBubble": bubble,
|
||||
"listView": listView,
|
||||
"author": UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author),
|
||||
"formattedTime": formattedTime
|
||||
});
|
||||
obj.open();
|
||||
share.isOpen = true;
|
||||
visible = true; // the PushButton stay visible as long the popup is open even if it's not hovered
|
||||
imageColor = JamiTheme.chatViewFooterImgHoverColor;
|
||||
normalColor = JamiTheme.hoveredButtonColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MessageBubble {
|
||||
@ -382,7 +440,7 @@ Control {
|
||||
property bool bubbleHovered
|
||||
property string imgSource
|
||||
|
||||
width: (root.type === Interaction.Type.TEXT ? root.textContentWidth + (IsEmojiOnly || root.bigMsg ? 0 : root.timeWidth + root.editedWidth) : innerContent.childrenRect.width)
|
||||
width: (root.type === Interaction.Type.TEXT || isDeleted ? root.textContentWidth + (IsEmojiOnly || root.bigMsg ? 0 : root.timeWidth + root.editedWidth) : innerContent.childrenRect.width)
|
||||
height: innerContent.childrenRect.height + (visible ? root.extraHeight : 0) + (root.bigMsg ? 15 : 0)
|
||||
|
||||
HoverHandler {
|
||||
@ -466,6 +524,11 @@ Control {
|
||||
MessagesAdapter.openUrl(root.hoveredLink);
|
||||
}
|
||||
}
|
||||
|
||||
onDoubleClicked: {
|
||||
MessagesAdapter.editId = "";
|
||||
MessagesAdapter.replyToId = Id;
|
||||
}
|
||||
property bool bubbleHovered: containsMouse || textHovered
|
||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
264
src/app/commoncomponents/ShareMessageMenu.qml
Normal file
264
src/app/commoncomponents/ShareMessageMenu.qml
Normal file
@ -0,0 +1,264 @@
|
||||
/*
|
||||
* 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, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import SortFilterProxyModel 0.2
|
||||
import "contextmenu"
|
||||
import "../commoncomponents"
|
||||
import "../mainview/components"
|
||||
|
||||
BaseContextMenu {
|
||||
id: mainMenu
|
||||
|
||||
height: 330 + Math.min(messageInput.height, textareaMaxHeight)
|
||||
width: 400
|
||||
|
||||
required property string msgId
|
||||
required property string msgBody
|
||||
required property bool isOutgoing
|
||||
required property int type
|
||||
required property string transferName
|
||||
required property Item msgBubble
|
||||
required property ListView listView
|
||||
required property string author
|
||||
required property string formattedTime
|
||||
|
||||
property var selectedUids: []
|
||||
property string shareToId: msgId
|
||||
property string fileLink: msgBody
|
||||
property int textareaMaxHeight: 350
|
||||
function xPosition(width) {
|
||||
// Use the width at function scope to retrigger property evaluation.
|
||||
const listViewWidth = listView.width;
|
||||
const parentX = parent.x;
|
||||
if (isOutgoing) {
|
||||
return parentX - width - 20;
|
||||
} else {
|
||||
return parentX + 20;
|
||||
}
|
||||
}
|
||||
|
||||
x: xPosition(width)
|
||||
y: parent.y
|
||||
|
||||
function xPositionProvider(width) {
|
||||
// Use the width at function scope to retrigger property evaluation.
|
||||
const listViewWidth = listView.width;
|
||||
if (isOutgoing) {
|
||||
return -5 - width;
|
||||
} else {
|
||||
const rightMargin = listViewWidth - (msgBubble.x + width);
|
||||
return width > rightMargin + 35 ? -5 - width : 35;
|
||||
}
|
||||
}
|
||||
function yPositionProvider(height) {
|
||||
const topOffset = msgBubble.mapToItem(listView, 0, 0).y;
|
||||
const listViewHeight = listView.height;
|
||||
const bottomMargin = listViewHeight - height - topOffset;
|
||||
if (bottomMargin < 0 || (topOffset < 0 && topOffset + height > 0)) {
|
||||
return 30 - height;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: shareConvProxyModel
|
||||
|
||||
sourceModel: ConversationsAdapter.convListProxyModel
|
||||
filterCaseSensitivity: Qt.CaseInsensitive
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: header
|
||||
|
||||
width: parent.width
|
||||
height: 0
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: sendButton
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 10
|
||||
anchors.topMargin: 10
|
||||
anchors.top: header.bottom
|
||||
color: JamiTheme.transparentColor
|
||||
|
||||
PushButton {
|
||||
id: shareMessageButton
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
width: scale * JamiTheme.chatViewFooterButtonSize
|
||||
anchors.right: parent.right
|
||||
|
||||
visible: true
|
||||
|
||||
radius: JamiTheme.chatViewFooterButtonRadius
|
||||
preferredSize: JamiTheme.chatViewFooterButtonIconSize - 6
|
||||
imageContainerWidth: 25
|
||||
imageContainerHeight: 25
|
||||
|
||||
toolTipText: JamiStrings.share
|
||||
|
||||
mirror: UtilsAdapter.isRTL
|
||||
|
||||
source: JamiResources.send_black_24dp_svg
|
||||
|
||||
hoverEnabled: enabled
|
||||
normalColor: enabled ? JamiTheme.chatViewFooterSendButtonColor : JamiTheme.chatViewFooterSendButtonDisableColor
|
||||
imageColor: enabled ? JamiTheme.chatViewFooterSendButtonImgColor : JamiTheme.chatViewFooterSendButtonImgColorDisable
|
||||
hoveredColor: JamiTheme.buttonTintedBlueHovered
|
||||
pressedColor: hoveredColor
|
||||
|
||||
opacity: 1
|
||||
scale: opacity
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
onClicked: {
|
||||
var selectedContacts = mainMenu.selectedUids;
|
||||
var hasText = messageInput.text && selectedContacts.length > 0;
|
||||
function sendMessageOrFile(uid) {
|
||||
if (Type === 2) {
|
||||
// 2=TEXT and 5=DATA_TRANSFER (any kind of file) defined in interaction.h
|
||||
MessagesAdapter.sendMessageToUid(msgBody, uid);
|
||||
} else {
|
||||
MessagesAdapter.sendFileToUid(fileLink, uid);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < selectedContacts.length; i++) {
|
||||
var uid = selectedContacts[i];
|
||||
sendMessageOrFile(uid);
|
||||
if (hasText) {
|
||||
MessagesAdapter.sendMessageToUid(messageInput.text, uid);
|
||||
}
|
||||
}
|
||||
messageInput.text = "";
|
||||
mainMenu.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: searchConv
|
||||
|
||||
height: 300
|
||||
width: parent.width
|
||||
anchors.top: header.bottom
|
||||
anchors.topMargin: 10
|
||||
|
||||
property int type: ContactList.CONVERSATION
|
||||
|
||||
color: JamiTheme.transparentColor
|
||||
ColumnLayout {
|
||||
id: contactPickerPopupRectColumnLayout
|
||||
|
||||
anchors.fill: parent
|
||||
Searchbar {
|
||||
id: contactPickerContactSearchBar
|
||||
|
||||
width: parent.width - 20 - JamiTheme.chatViewFooterButtonSize
|
||||
anchors.leftMargin: 10
|
||||
Layout.preferredHeight: 35
|
||||
placeHolderText: "Share to..."
|
||||
onSearchBarTextChanged: function (text) {
|
||||
shareConvProxyModel.filterRole = shareConvProxyModel.roleForName("Title");
|
||||
shareConvProxyModel.filterPattern = text;
|
||||
}
|
||||
}
|
||||
JamiListView {
|
||||
id: contactPickerListView
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 255
|
||||
Layout.bottomMargin: JamiTheme.preferredMarginSize
|
||||
Layout.topMargin: 5
|
||||
|
||||
model: shareConvProxyModel
|
||||
|
||||
delegate: ConversationPickerItemDelegate {
|
||||
id: conversationDelegate
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flickable {
|
||||
id: messageInputContainer
|
||||
|
||||
height: Math.min(contentHeight, mainMenu.textareaMaxHeight)
|
||||
width: parent.width - 20
|
||||
contentHeight: messageInput.height
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 10
|
||||
anchors.rightMargin: 10
|
||||
anchors.topMargin: 10
|
||||
anchors.top: searchConv.bottom
|
||||
|
||||
flickableDirection: Flickable.VerticalFlick
|
||||
clip: true
|
||||
|
||||
ScrollBar.vertical: JamiScrollBar {
|
||||
policy: ScrollBar.AsNeeded
|
||||
}
|
||||
|
||||
onContentHeightChanged: {
|
||||
if (contentHeight > height) {
|
||||
contentY = contentHeight - height;
|
||||
}
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: messageInput
|
||||
|
||||
height: contentHeight + 12
|
||||
width: parent.width
|
||||
placeholderText: "Add a comment"
|
||||
placeholderTextColor: JamiTheme.messageBarPlaceholderTextColor
|
||||
font.pointSize: JamiTheme.textFontSize + 2
|
||||
color: JamiTheme.textColor
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
background: Rectangle {
|
||||
color: JamiTheme.transparentColor
|
||||
radius: 5
|
||||
border.color: JamiTheme.chatViewFooterRectangleBorderColor
|
||||
border.width: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// destroy() and setBindings() are needed to unselect the share icon from SBSMessageBase
|
||||
|
||||
onAboutToHide: {
|
||||
mainMenu.destroy();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
parent.setBindings();
|
||||
}
|
||||
}
|
||||
@ -89,8 +89,10 @@ BaseContextMenu {
|
||||
emojiPicker.emojiIsPicked.connect(function (content) {
|
||||
if (emojiReplied.includes(content)) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId);
|
||||
parent.setBindings();
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId);
|
||||
parent.setBindings();
|
||||
}
|
||||
});
|
||||
if (emojiPicker !== null) {
|
||||
@ -107,8 +109,11 @@ BaseContextMenu {
|
||||
property bool isScrolling: listView.verticalScrollBar.active
|
||||
|
||||
onOpened: root.closeWithoutAnimation = false
|
||||
onClosed: if (emojiPicker)
|
||||
emojiPicker.closeEmojiPicker()
|
||||
onClosed: {
|
||||
if (emojiPicker) {
|
||||
emojiPicker.closeEmojiPicker();
|
||||
}
|
||||
}
|
||||
|
||||
function getQuickEmojiListModel() {
|
||||
const defaultModel = ["👍", "👎", "😂"];
|
||||
@ -153,7 +158,7 @@ BaseContextMenu {
|
||||
GeneralMenuItem {
|
||||
id: removeLocally
|
||||
|
||||
canTrigger: type === Interaction.Type.DATA_TRANSFER && Status === Interaction.Status.TRANSFER_FINISHED
|
||||
canTrigger: type === Interaction.Type.DATA_TRANSFER && TransferStatus === Interaction.TransferStatus.TRANSFER_FINISHED
|
||||
iconSource: JamiResources.trash_black_24dp_svg
|
||||
itemName: JamiStrings.removeLocally
|
||||
onClicked: {
|
||||
@ -175,7 +180,7 @@ BaseContextMenu {
|
||||
GeneralMenuItem {
|
||||
id: deleteMessage
|
||||
|
||||
canTrigger: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
canTrigger: root.isOutgoing && (type === Interaction.Type.TEXT || type === Interaction.Type.DATA_TRANSFER)
|
||||
iconSource: JamiResources.delete_svg
|
||||
itemName: JamiStrings.deleteMessage
|
||||
onClicked: {
|
||||
@ -198,11 +203,13 @@ BaseContextMenu {
|
||||
root.loadMenuItems(menuItems);
|
||||
}
|
||||
|
||||
// destroy() and setBindings() are needed to unselect the share icon from SBSMessageBase
|
||||
|
||||
onAboutToHide: {
|
||||
root.destroy();
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
parent.bind();
|
||||
parent.setBindings();
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ ConversationListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s
|
||||
}
|
||||
} else {
|
||||
Q_FOREACH (const auto& filter, toFilter)
|
||||
if (rx.match(filter).hasMatch()) {
|
||||
if (rx.isValid() && rx.match(filter).hasMatch()) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
|
||||
}
|
||||
case Role::Draft: {
|
||||
if (!item.uid.isEmpty())
|
||||
return lrcInstance_->getContentDraft(item.uid, item.accountId);
|
||||
return lrcInstance_->getContentDraft(item.uid, item.accountId)["text"];
|
||||
return {};
|
||||
}
|
||||
case Role::ActiveCallsCount: {
|
||||
@ -125,7 +125,11 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
|
||||
if (interaction.type == interaction::Type::UPDATE_PROFILE) {
|
||||
lastInteractionBody = interaction::getProfileUpdatedString();
|
||||
} else if (interaction.type == interaction::Type::DATA_TRANSFER) {
|
||||
lastInteractionBody = interaction.commit.value("displayName");
|
||||
if (interaction.commit.value("tid").isEmpty()) {
|
||||
lastInteractionBody = tr("Deleted media");
|
||||
} else {
|
||||
lastInteractionBody = interaction.commit.value("displayName");
|
||||
}
|
||||
} else if (interaction.type == lrc::api::interaction::Type::CALL) {
|
||||
const auto isOutgoing = interaction.authorUri == accInfo.profileInfo.uri;
|
||||
lastInteractionBody = interaction::getCallInteractionString(isOutgoing, interaction);
|
||||
@ -133,7 +137,7 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
|
||||
auto bestName = interaction.authorUri == accInfo.profileInfo.uri
|
||||
? accInfo.accountModel->bestNameForAccount(accInfo.id)
|
||||
: accInfo.contactModel->bestNameForContact(
|
||||
interaction.authorUri);
|
||||
interaction.authorUri);
|
||||
lastInteractionBody
|
||||
= interaction::getContactInteractionString(bestName,
|
||||
interaction::to_action(
|
||||
|
||||
@ -152,7 +152,7 @@ CurrentConversation::updateData()
|
||||
updateProfile(convId);
|
||||
updateActiveCalls(accountId, convId);
|
||||
} catch (...) {
|
||||
qWarning() << "Can't update current conversation data for" << convId;
|
||||
qWarning() << "An error occurred while updating current conversation data for" << convId;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -29,13 +29,13 @@ void
|
||||
DBusErrorHandler::errorCallback()
|
||||
{
|
||||
qDebug() << "Dring has possibly crashed, "
|
||||
"or has been killed... will wait 2.5 seconds and try to reconnect";
|
||||
"or has been killed… will wait 2.5 seconds before attempting to reconnect.";
|
||||
|
||||
Q_EMIT showDaemonReconnectPopup(true);
|
||||
|
||||
QTimer::singleShot(2500, this, [this]() {
|
||||
if ((!lrc::api::Lrc::isConnected()) || (!lrc::api::Lrc::dbusIsValid())) {
|
||||
qDebug() << "Could not reconnect to the daemon";
|
||||
qDebug() << "An error occurred while attempting to reconnect to the daemon.";
|
||||
Q_EMIT daemonReconnectFailed();
|
||||
} else {
|
||||
static_cast<DBusErrorHandler&>(GlobalInstances::dBusErrorHandler())
|
||||
|
||||
2
src/app/js/.clang-format
Normal file
2
src/app/js/.clang-format
Normal file
@ -0,0 +1,2 @@
|
||||
Language: JavaScript
|
||||
BasedOnStyle: Google
|
||||
279
src/app/js/markdownedition.js
Normal file
279
src/app/js/markdownedition.js
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// This file contains the functions that allow the user to format the text in
|
||||
// the message bar by adding bold, italic, underline, strikethrough, ordered
|
||||
// list, and unordered list styles.
|
||||
|
||||
function isStyle(ta, text, char1, char2) {
|
||||
const start = ta.selectionStart;
|
||||
const end = ta.selectionEnd;
|
||||
|
||||
if (char1 === '**') {
|
||||
return isStarStyle(ta, text, 'bold');
|
||||
}
|
||||
if (char1 === '*') {
|
||||
return isStarStyle(ta, text, 'italic');
|
||||
}
|
||||
const selectedText = text.substring(start - char1.length, end + char2.length);
|
||||
return (selectedText.startsWith(char1) && selectedText.endsWith(char2));
|
||||
}
|
||||
|
||||
function isStarStyle(ta, text, type) {
|
||||
const selectionStart = ta.selectionStart;
|
||||
const selectionEnd = ta.selectionEnd;
|
||||
|
||||
let start = selectionStart;
|
||||
while (start > 0 && text[start - 1] === '*') {
|
||||
start--;
|
||||
}
|
||||
let end = selectionEnd;
|
||||
while (end < text.length && text[end] === '*') {
|
||||
end++;
|
||||
}
|
||||
const starCount = Math.min(selectionStart - start, end - selectionEnd);
|
||||
if (type === 'italic') {
|
||||
return starCount === 1 || starCount === 3;
|
||||
}
|
||||
return starCount === 2 || starCount === 3;
|
||||
}
|
||||
|
||||
function addStyle(ta, text, char1, char2) {
|
||||
const start = ta.selectionStart;
|
||||
const end = ta.selectionEnd;
|
||||
|
||||
// Get the selected text with markdown effect
|
||||
var selectedText = text.substring(start - char1.length, end + char2.length);
|
||||
|
||||
// If the selected text is already formatted with the given characters, remove
|
||||
// them
|
||||
if (isStyle(ta, text, char1, char2)) {
|
||||
selectedText = text.substring(start, end);
|
||||
ta.text = text.substring(0, start - char1.length) + selectedText +
|
||||
text.substring(end + char2.length);
|
||||
ta.selectText(start - char1.length, end - char1.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, add the formatting characters to the selected text
|
||||
ta.text = text.substring(0, start) + char1 + text.substring(start, end) +
|
||||
char2 + text.substring(end);
|
||||
ta.selectText(start + char1.length, end + char1.length);
|
||||
}
|
||||
|
||||
function isPrefixSyle(ta, message, delimiter, isOrderedList) {
|
||||
const selectionStart = ta.selectionStart;
|
||||
const selectionEnd = ta.selectionEnd;
|
||||
|
||||
// Represents all the selected lines
|
||||
var multilineSelection;
|
||||
var newPrefix;
|
||||
var newSuffix;
|
||||
var newStartPos;
|
||||
var newEndPos;
|
||||
function nextIndexOf(text, char1, startPos) {
|
||||
return text.indexOf(char1, startPos + 1);
|
||||
}
|
||||
|
||||
// Get the previous index of the multilineSelection text
|
||||
if (message[selectionStart] === '\n')
|
||||
newStartPos = message.lastIndexOf('\n', selectionStart - 1);
|
||||
else
|
||||
newStartPos = message.lastIndexOf('\n', selectionStart);
|
||||
|
||||
// Get the next index of the multilineSelection text
|
||||
if (message[selectionEnd] === '\n' || message[selectionEnd] === undefined)
|
||||
newEndPos = selectionEnd;
|
||||
else
|
||||
newEndPos = nextIndexOf(message, '\n', selectionEnd);
|
||||
|
||||
// If the text is empty
|
||||
if (newStartPos === -1) newStartPos = 0;
|
||||
newPrefix = message.slice(0, newStartPos);
|
||||
multilineSelection = message.slice(newStartPos, newEndPos);
|
||||
newSuffix = message.slice(newEndPos);
|
||||
var isFirstLineSelected =
|
||||
!multilineSelection.startsWith('\n') || newPrefix === '';
|
||||
var getDelimiter_counter = 1;
|
||||
function getDelimiter() {
|
||||
return `${getDelimiter_counter++}. `;
|
||||
}
|
||||
function getHasCurrentMarkdown() {
|
||||
const linesQuantity = (multilineSelection.match(/\n/g) || []).length;
|
||||
const newLinesWithDelimitersQuantity =
|
||||
(multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) ||
|
||||
[]).length;
|
||||
if (newLinesWithDelimitersQuantity === linesQuantity &&
|
||||
!isFirstLineSelected)
|
||||
return true;
|
||||
return linesQuantity === newLinesWithDelimitersQuantity &&
|
||||
multilineSelection.startsWith(delimiter);
|
||||
}
|
||||
function getHasCurrentMarkdownBullet() {
|
||||
const linesQuantity = (multilineSelection.match(/\n/g) || []).length;
|
||||
const newLinesWithDelimitersQuantity =
|
||||
(multilineSelection.match(/\n\d+\. /g) || []).length;
|
||||
if (newLinesWithDelimitersQuantity === linesQuantity &&
|
||||
!isFirstLineSelected)
|
||||
return true;
|
||||
return linesQuantity === newLinesWithDelimitersQuantity &&
|
||||
(/^\d\. /).test(multilineSelection);
|
||||
}
|
||||
var newValue;
|
||||
var newStart;
|
||||
var newEnd;
|
||||
var count;
|
||||
var startPos;
|
||||
var multilineSelectionLength;
|
||||
if (!isOrderedList) {
|
||||
return getHasCurrentMarkdown();
|
||||
} else {
|
||||
return getHasCurrentMarkdownBullet();
|
||||
}
|
||||
}
|
||||
|
||||
function addPrefixStyle(ta, message, delimiter, isOrderedList) {
|
||||
const selectionStart = ta.selectionStart;
|
||||
const selectionEnd = ta.selectionEnd;
|
||||
|
||||
// Represents all the selected lines
|
||||
var multilineSelection;
|
||||
var newPrefix;
|
||||
var newSuffix;
|
||||
var newStartPos;
|
||||
var newEndPos;
|
||||
function nextIndexOf(text, char1, startPos) {
|
||||
return text.indexOf(char1, startPos + 1);
|
||||
}
|
||||
|
||||
// Get the previous index of the multilineSelection text
|
||||
if (message[selectionStart] === '\n')
|
||||
newStartPos = message.lastIndexOf('\n', selectionStart - 1);
|
||||
else
|
||||
newStartPos = message.lastIndexOf('\n', selectionStart);
|
||||
|
||||
// Get the next index of the multilineSelection text
|
||||
if (message[selectionEnd] === '\n' || message[selectionEnd] === undefined)
|
||||
newEndPos = selectionEnd;
|
||||
else
|
||||
newEndPos = nextIndexOf(message, '\n', selectionEnd);
|
||||
|
||||
// If the text is empty
|
||||
if (newStartPos === -1) newStartPos = 0;
|
||||
newPrefix = message.slice(0, newStartPos);
|
||||
multilineSelection = message.slice(newStartPos, newEndPos);
|
||||
newSuffix = message.slice(newEndPos);
|
||||
var isFirstLineSelected =
|
||||
!multilineSelection.startsWith('\n') || newPrefix === '';
|
||||
var getDelimiter_counter = 1;
|
||||
function getDelimiter() {
|
||||
return `${getDelimiter_counter++}. `;
|
||||
}
|
||||
function getHasCurrentMarkdown() {
|
||||
const linesQuantity = (multilineSelection.match(/\n/g) || []).length;
|
||||
const newLinesWithDelimitersQuantity =
|
||||
(multilineSelection.match(new RegExp(`\n${delimiter}`, 'g')) ||
|
||||
[]).length;
|
||||
if (newLinesWithDelimitersQuantity === linesQuantity &&
|
||||
!isFirstLineSelected)
|
||||
return true;
|
||||
return linesQuantity === newLinesWithDelimitersQuantity &&
|
||||
multilineSelection.startsWith(delimiter);
|
||||
}
|
||||
function getHasCurrentMarkdownBullet() {
|
||||
const linesQuantity = (multilineSelection.match(/\n/g) || []).length;
|
||||
const newLinesWithDelimitersQuantity =
|
||||
(multilineSelection.match(/\n\d+\. /g) || []).length;
|
||||
if (newLinesWithDelimitersQuantity === linesQuantity &&
|
||||
!isFirstLineSelected)
|
||||
return true;
|
||||
return linesQuantity === newLinesWithDelimitersQuantity &&
|
||||
(/^\d\. /).test(multilineSelection);
|
||||
}
|
||||
var newValue;
|
||||
var newStart;
|
||||
var newEnd;
|
||||
var count;
|
||||
var startPos;
|
||||
var multilineSelectionLength;
|
||||
if (!isOrderedList) {
|
||||
if (getHasCurrentMarkdown()) {
|
||||
// Clear first line from delimiter
|
||||
if (isFirstLineSelected)
|
||||
multilineSelection = multilineSelection.slice(delimiter.length);
|
||||
newValue = newPrefix +
|
||||
multilineSelection.replace(new RegExp(`\n${delimiter}`, 'g'), '\n') +
|
||||
newSuffix;
|
||||
count = 0;
|
||||
if (isFirstLineSelected) count++;
|
||||
count += (multilineSelection.match(/\n/g) || []).length;
|
||||
newStart = Math.max(selectionStart - delimiter.length, 0);
|
||||
newEnd = Math.max(selectionEnd - (delimiter.length * count), 0);
|
||||
} else {
|
||||
newValue = newPrefix +
|
||||
multilineSelection.replace(/\n/g, `\n${delimiter}`) + newSuffix;
|
||||
count = 0;
|
||||
if (isFirstLineSelected) {
|
||||
newValue = delimiter + newValue;
|
||||
count++;
|
||||
}
|
||||
count += (multilineSelection.match(new RegExp('\\n', 'g')) || []).length;
|
||||
newStart = selectionStart + delimiter.length;
|
||||
newEnd = selectionEnd + (delimiter.length * count);
|
||||
}
|
||||
} else if (getHasCurrentMarkdownBullet()) {
|
||||
if (message[selectionStart] === '\n')
|
||||
startPos = message.lastIndexOf('\n', selectionStart - 1) + 1;
|
||||
else
|
||||
startPos = message.lastIndexOf('\n', selectionStart) + 1;
|
||||
newStart = startPos;
|
||||
multilineSelection = multilineSelection.replace(/^\d+\.\s/gm, '');
|
||||
newValue = newPrefix + multilineSelection + newSuffix;
|
||||
multilineSelectionLength = multilineSelection.length;
|
||||
|
||||
// If the first line is not selected, we need to remove the first "\n" of
|
||||
// multilineSelection
|
||||
if (newStart) multilineSelectionLength = multilineSelection.length - 1;
|
||||
newEnd = Math.max(newStart + multilineSelectionLength, 0);
|
||||
} else {
|
||||
if (message[selectionStart] === '\n')
|
||||
startPos = message.lastIndexOf('\n', selectionStart - 1) + 1;
|
||||
else
|
||||
startPos = message.lastIndexOf('\n', selectionStart) + 1;
|
||||
newStart = startPos;
|
||||
|
||||
// If no text is selected
|
||||
if (selectionStart === selectionEnd) newStart = newStart + 3;
|
||||
if (isFirstLineSelected)
|
||||
multilineSelection = getDelimiter() + multilineSelection;
|
||||
const selectionArr = Array.from(multilineSelection);
|
||||
for (var i = 0; i < selectionArr.length; i++) {
|
||||
if (selectionArr[i] === '\n') selectionArr[i] = `\n${getDelimiter()}`;
|
||||
}
|
||||
multilineSelection = selectionArr.join('');
|
||||
newValue = newPrefix + multilineSelection + newSuffix;
|
||||
multilineSelectionLength = multilineSelection.length;
|
||||
|
||||
// If the first line is not selected, we meed to remove the first "\n" of
|
||||
// multilineSelection
|
||||
if (startPos) multilineSelectionLength = multilineSelection.length - 1;
|
||||
newEnd = Math.max(startPos + multilineSelectionLength, 0);
|
||||
}
|
||||
|
||||
ta.text = newValue;
|
||||
ta.selectText(newStart, newEnd);
|
||||
}
|
||||
@ -43,9 +43,8 @@ LRCInstance::LRCInstance(const QString& updateUrl,
|
||||
muteDaemon_ = muteDaemon;
|
||||
threadPool_->setMaxThreadCount(1);
|
||||
|
||||
connect(this, &LRCInstance::currentAccountIdChanged, [this] {
|
||||
// save to config, editing the accountlistmodel's underlying data
|
||||
accountModel().setTopAccount(currentAccountId_);
|
||||
// Update the current account when the account list changes.
|
||||
connect(&accountModel(), &AccountModel::accountsReordered, this, [this] {
|
||||
Q_EMIT accountListChanged();
|
||||
|
||||
profile::Info profileInfo;
|
||||
@ -62,6 +61,11 @@ LRCInstance::LRCInstance(const QString& updateUrl,
|
||||
set_currentAccountAvatarSet(!profileInfo.avatar.isEmpty());
|
||||
});
|
||||
|
||||
connect(this, &LRCInstance::currentAccountIdChanged, [this] {
|
||||
// This will trigger `AccountModel::accountsReordered`.
|
||||
accountModel().setTopAccount(currentAccountId_);
|
||||
});
|
||||
|
||||
connect(&accountModel(), &AccountModel::profileUpdated, this, [this](const QString& id) {
|
||||
if (id != currentAccountId_)
|
||||
return;
|
||||
@ -348,30 +352,36 @@ LRCInstance::stopAudioMeter()
|
||||
});
|
||||
}
|
||||
|
||||
QString
|
||||
QVariantMap
|
||||
LRCInstance::getContentDraft(const QString& convUid, const QString& accountId)
|
||||
{
|
||||
auto draftKey = accountId + "_" + convUid;
|
||||
return contentDrafts_[draftKey];
|
||||
QVariantMap draftMap;
|
||||
draftMap["text"] = contentDrafts_[draftKey];
|
||||
draftMap["files"] = fileDrafts_[draftKey];
|
||||
|
||||
return draftMap;
|
||||
}
|
||||
|
||||
void
|
||||
LRCInstance::setContentDraft(const QString& convUid,
|
||||
const QString& accountId,
|
||||
const QString& content)
|
||||
const QString& textDraft,
|
||||
const QList<QString>& filePathDraft)
|
||||
{
|
||||
if (accountId.isEmpty() || convUid.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto draftKey = accountId + "_" + convUid;
|
||||
|
||||
// prevent a senseless dataChanged signal from the
|
||||
// model if nothing has changed
|
||||
if (contentDrafts_[draftKey] == content)
|
||||
if (contentDrafts_[draftKey] == textDraft && fileDrafts_[draftKey] == filePathDraft) {
|
||||
return;
|
||||
}
|
||||
|
||||
contentDrafts_[draftKey] = content;
|
||||
contentDrafts_[draftKey] = textDraft;
|
||||
fileDrafts_[draftKey] = filePathDraft;
|
||||
// this signal is only needed to update the current smartlist
|
||||
Q_EMIT draftSaved(convUid);
|
||||
}
|
||||
|
||||
@ -102,10 +102,12 @@ public:
|
||||
Q_INVOKABLE void deselectConversation();
|
||||
Q_INVOKABLE void makeConversationPermanent(const QString& convId = {},
|
||||
const QString& accountId = {});
|
||||
Q_INVOKABLE QString getContentDraft(const QString& convUid, const QString& accountId);
|
||||
Q_INVOKABLE QVariantMap getContentDraft(const QString& convUid, const QString& accountId);
|
||||
Q_INVOKABLE void setContentDraft(const QString& convUid,
|
||||
const QString& accountId,
|
||||
const QString& content);
|
||||
const QString& textDraft,
|
||||
const QList<QString>& filePathDraft);
|
||||
|
||||
Q_INVOKABLE int indexOfActiveCall(const QString& confId,
|
||||
const QString& uri,
|
||||
const QString& deviceId);
|
||||
@ -157,6 +159,7 @@ private:
|
||||
QString selectedConvUid_;
|
||||
MapStringString contentDrafts_;
|
||||
MapStringString lastConferences_;
|
||||
MapStringListString fileDrafts_;
|
||||
|
||||
conversation::Info invalid {"", nullptr};
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import Qt5Compat.GraphicalEffects
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Helpers 1.1
|
||||
import "../../commoncomponents"
|
||||
|
||||
BaseModalDialog {
|
||||
@ -63,23 +64,21 @@ BaseModalDialog {
|
||||
source: JamiTheme.darkTheme ? JamiResources.logo_jami_standard_coul_white_svg : JamiResources.logo_jami_standard_coul_svg
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: JamiTheme.backgroundRectangleColor
|
||||
Control {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
radius: 5
|
||||
|
||||
ColumnLayout {
|
||||
id: sloganLayout
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
background: Rectangle {
|
||||
color: JamiTheme.backgroundRectangleColor
|
||||
radius: 5
|
||||
}
|
||||
|
||||
padding: 10
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 4
|
||||
TextEdit {
|
||||
id: jamiSlogansText
|
||||
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.margins: 10
|
||||
Layout.bottomMargin: 0
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: JamiTheme.menuFontSize
|
||||
@ -100,23 +99,30 @@ BaseModalDialog {
|
||||
}
|
||||
}
|
||||
TextEdit {
|
||||
id: jamiVersionText
|
||||
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.margins: 10
|
||||
Layout.topMargin: 0
|
||||
Layout.maximumWidth: JamiTheme.preferredDialogWidth - 2*JamiTheme.preferredMarginSize
|
||||
|
||||
font.pixelSize: JamiTheme.textFontSize
|
||||
padding: 0
|
||||
text: JamiStrings.version + ": " + UtilsAdapter.getVersionStr()
|
||||
readonly property bool isBeta: AppVersionManager.isCurrentVersionBeta()
|
||||
text: {
|
||||
// HACK: Only display the version string if it has been constructed properly.
|
||||
// This is a workaround for an issue that occurs due to the way Linux
|
||||
// packaging is done, where the git repository is not available in the
|
||||
// build source at configure time, which is when the version files are
|
||||
// generated, so we prevent a "." from being displayed if the version
|
||||
// string is not available.
|
||||
var contentStr = JamiStrings.buildID + ": " + UtilsAdapter.getBuildIDStr();
|
||||
const versionStr = UtilsAdapter.getVersionStr()
|
||||
if (versionStr.length > 1) {
|
||||
contentStr += "\n" + JamiStrings.version + ": " + (isBeta ? "(Beta) " : "") + versionStr
|
||||
}
|
||||
return contentStr
|
||||
}
|
||||
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
|
||||
color: JamiTheme.faddedFontColor
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,24 +34,6 @@ Label {
|
||||
|
||||
property bool inSettings: viewCoordinator.currentViewName === "SettingsView"
|
||||
|
||||
// TODO: remove these refresh hacks use QAbstractItemModels correctly
|
||||
Connections {
|
||||
target: AccountAdapter
|
||||
|
||||
function onAccountStatusChanged(accountId) {
|
||||
AccountListModel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: LRCInstance
|
||||
|
||||
function onAccountListChanged() {
|
||||
root.update();
|
||||
AccountListModel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
function togglePopup() {
|
||||
if (root.popup.opened) {
|
||||
root.popup.close();
|
||||
|
||||
@ -60,23 +60,6 @@ Popup {
|
||||
|
||||
property bool inSettings: viewCoordinator.currentViewName === "SettingsView"
|
||||
|
||||
// TODO: remove these refresh hacks use QAbstractItemModels correctly
|
||||
Connections {
|
||||
target: AccountAdapter
|
||||
|
||||
function onAccountStatusChanged(accountId) {
|
||||
AccountListModel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: LRCInstance
|
||||
|
||||
function onAccountListChanged() {
|
||||
AccountListModel.reset();
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: mainLayout
|
||||
anchors.fill: parent
|
||||
@ -257,11 +240,6 @@ Popup {
|
||||
color: JamiTheme.smartListHoveredColor
|
||||
}
|
||||
|
||||
// fake footer item as workaround for Qt 5.15 bug
|
||||
// https://bugreports.qt.io/browse/QTBUG-85302
|
||||
// don't use the clip trick and footer item overlay
|
||||
// explained here https://stackoverflow.com/a/64625149
|
||||
// as it causes other complexities in handling the drop shadow
|
||||
ItemDelegate {
|
||||
id: addAccountItem
|
||||
|
||||
|
||||
@ -42,7 +42,7 @@ Rectangle {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 35
|
||||
|
||||
placeHolderText: JamiStrings.addParticipant
|
||||
placeHolderText: JamiStrings.inviteMember
|
||||
|
||||
onSearchBarTextChanged: function(text){
|
||||
ContactAdapter.setSearchFilter(text);
|
||||
|
||||
@ -315,7 +315,7 @@ Control {
|
||||
checkable: true
|
||||
icon.source: checked ? JamiResources.videocam_off_24dp_svg : JamiResources.videocam_24dp_svg
|
||||
icon.color: checked ? "red" : "white"
|
||||
text: !checked ? JamiStrings.muteCamera : JamiStrings.unmuteCamera
|
||||
text: !checked ? JamiStrings.stopCamera : JamiStrings.startCamera
|
||||
checked: !CurrentCall.isCapturing
|
||||
property var menuAction: videoInputMenuAction
|
||||
enabled: CurrentAccount.videoEnabled_Video
|
||||
@ -339,7 +339,7 @@ Control {
|
||||
onTriggered: root.addToConferenceClicked()
|
||||
icon.source: JamiResources.add_people_black_24dp_svg
|
||||
icon.color: "white"
|
||||
text: JamiStrings.addParticipants
|
||||
text: JamiStrings.inviteMembers
|
||||
enabled: CurrentCall.isModerator && !CurrentCall.isSIP
|
||||
onEnabledChanged: CallOverlayModel.setEnabled(this, addPersonAction.enabled)
|
||||
},
|
||||
@ -437,7 +437,7 @@ Control {
|
||||
onTriggered: root.pluginsClicked()
|
||||
icon.source: JamiResources.plugins_24dp_svg
|
||||
icon.color: "white"
|
||||
text: JamiStrings.viewPlugin
|
||||
text: JamiStrings.viewExtension
|
||||
enabled: PluginAdapter.callMediaHandlersListCount
|
||||
onEnabledChanged: CallOverlayModel.setEnabled(this, pluginsAction.enabled)
|
||||
},
|
||||
|
||||
@ -27,6 +27,14 @@ import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
|
||||
Rectangle {
|
||||
id: root
|
||||
|
||||
// HACK: Added to capture the mouse when the layouts start stacking.
|
||||
// The header and footer we're unable to be interacted with otherwise.
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
propagateComposedEvents: false
|
||||
enabled: viewCoordinator.isInSinglePaneMode
|
||||
}
|
||||
|
||||
// An enum to make the details panels more readable.
|
||||
enum ExtrasPanel {
|
||||
SwarmDetailsPanel,
|
||||
@ -133,8 +141,13 @@ Rectangle {
|
||||
target: CurrentConversation
|
||||
|
||||
function onIdChanged() {
|
||||
if (!chatViewHeader.interactionButtonsVisibility)
|
||||
if (!chatViewHeader.detailsButtonVisibility) {
|
||||
extrasPanel.closePanel();
|
||||
} else if (width < JamiTheme.mainViewMinWidth + extrasPanel.width) {
|
||||
extrasPanel.closePanel();
|
||||
} else if (!chatViewHeader.interactionButtonsVisibility) {
|
||||
extrasPanel.closePanel();
|
||||
}
|
||||
}
|
||||
|
||||
function onNeedsHost() {
|
||||
|
||||
@ -43,17 +43,31 @@ Rectangle {
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
|
||||
function updateMessageDraft() {
|
||||
LRCInstance.setContentDraft(previousConvId, previousAccountId, messageBar.text);
|
||||
// Store the current files that have not been sent, if any. Do the same for the message draft.
|
||||
var filePathDraft = [];
|
||||
while(messageBar.fileContainer.filesToSendCount > 0) {
|
||||
var currentIndex = messageBar.fileContainer.filesToSendListModel.index(0, 0);
|
||||
var filePath = messageBar.fileContainer.filesToSendListModel.data(currentIndex, FilesToSend.FilePath);
|
||||
filePathDraft.push(filePath);
|
||||
messageBar.fileContainer.filesToSendListModel.removeFromPending(0);
|
||||
}
|
||||
LRCInstance.setContentDraft(previousConvId, previousAccountId, messageBar.text, filePathDraft);
|
||||
previousConvId = CurrentConversation.id;
|
||||
previousAccountId = CurrentAccount.id;
|
||||
|
||||
// turn off the button animations when switching convs
|
||||
messageBar.animate = false;
|
||||
messageBar.textAreaObj.clearText();
|
||||
|
||||
// restore the draft state of contents for a specific conversation
|
||||
var restoredContent = LRCInstance.getContentDraft(CurrentConversation.id, CurrentAccount.id);
|
||||
if (restoredContent) {
|
||||
messageBar.textAreaObj.insertText(restoredContent);
|
||||
messageBar.textAreaObj.insertText(restoredContent["text"]);
|
||||
for (var i = 0; i < restoredContent["files"].length; ++i) {
|
||||
messageBar.fileContainer.filesToSendListModel.addToPending(restoredContent["files"][i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Connections {
|
||||
@ -134,7 +148,7 @@ Rectangle {
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: footerColumnLayout.width
|
||||
Layout.leftMargin: 0
|
||||
Layout.leftMargin: marginSize
|
||||
Layout.rightMargin: marginSize
|
||||
Layout.bottomMargin: marginSize
|
||||
Layout.preferredHeight: height
|
||||
|
||||
@ -23,7 +23,6 @@ import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Enums 1.1
|
||||
import net.jami.Models 1.1
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
Rectangle {
|
||||
@ -46,6 +45,8 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
property bool detailsButtonVisibility: detailsButton.visible
|
||||
|
||||
readonly property bool interactionButtonsVisibility: {
|
||||
if (CurrentConversation.inCall)
|
||||
return false;
|
||||
@ -59,9 +60,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
property bool addMemberVisibility: {
|
||||
return swarmDetailsVisibility
|
||||
&& !CurrentConversation.isCoreDialog
|
||||
&& !CurrentConversation.isRequest;
|
||||
return swarmDetailsVisibility && !CurrentConversation.isCoreDialog && !CurrentConversation.isRequest;
|
||||
}
|
||||
|
||||
property bool swarmDetailsVisibility: {
|
||||
@ -79,8 +78,10 @@ Rectangle {
|
||||
anchors.rightMargin: 10 + layoutManager.qwkSystemButtonSpacing.right
|
||||
spacing: 16
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
JamiPushButton {
|
||||
id: backToWelcomeViewButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: 8
|
||||
@ -88,7 +89,7 @@ Rectangle {
|
||||
mirror: UtilsAdapter.isRTL
|
||||
|
||||
source: JamiResources.back_24dp_svg
|
||||
toolTipText: CurrentConversation.inCall ? JamiStrings.backCall : JamiStrings.hideChat
|
||||
toolTipText: CurrentConversation.inCall ? JamiStrings.returnToCall : JamiStrings.hideChat
|
||||
|
||||
onClicked: root.backClicked()
|
||||
}
|
||||
@ -107,8 +108,10 @@ Rectangle {
|
||||
|
||||
color: JamiTheme.transparentColor
|
||||
|
||||
ColumnLayout { QWKSetParentHitTestVisible {}
|
||||
ColumnLayout {
|
||||
id: userNameOrIdColumnLayout
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
objectName: "userNameOrIdColumnLayout"
|
||||
|
||||
height: parent.height
|
||||
@ -146,72 +149,79 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
id: startAAudioCallButton
|
||||
JamiPushButton {
|
||||
id: startAudioCallButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
|
||||
visible: interactionButtonsVisibility &&
|
||||
(!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||
visible: interactionButtonsVisibility && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||
source: JamiResources.place_audiocall_24dp_svg
|
||||
toolTipText: JamiStrings.placeAudioCall
|
||||
toolTipText: JamiStrings.startAudioCall
|
||||
|
||||
onClicked: CallAdapter.placeAudioOnlyCall()
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
id: startAVideoCallButton
|
||||
JamiPushButton {
|
||||
id: startVideoCallButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
|
||||
visible: interactionButtonsVisibility &&
|
||||
CurrentAccount.videoEnabled_Video &&
|
||||
(!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||
visible: interactionButtonsVisibility && CurrentAccount.videoEnabled_Video && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||
source: JamiResources.videocam_24dp_svg
|
||||
toolTipText: JamiStrings.placeVideoCall
|
||||
toolTipText: JamiStrings.startVideoCall
|
||||
|
||||
onClicked: CallAdapter.placeCall()
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
id: addParticipantsButton
|
||||
JamiPushButton {
|
||||
id: inviteMembersButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
|
||||
checkable: true
|
||||
checked: extrasPanel.isOpen(ChatView.AddMemberPanel)
|
||||
visible: interactionButtonsVisibility && addMemberVisibility
|
||||
source: JamiResources.add_people_24dp_svg
|
||||
toolTipText: JamiStrings.addParticipants
|
||||
toolTipText: JamiStrings.inviteMembers
|
||||
|
||||
onClicked: extrasPanel.switchToPanel(ChatView.AddMemberPanel)
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
id: selectPluginButton
|
||||
JamiPushButton {
|
||||
id: selectExtensionsButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
|
||||
visible: PluginAdapter.chatHandlersListCount && interactionButtonsVisibility
|
||||
source: JamiResources.plugins_24dp_svg
|
||||
toolTipText: JamiStrings.showPlugins
|
||||
toolTipText: JamiStrings.showExtensions
|
||||
|
||||
onClicked: pluginSelector()
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
JamiPushButton {
|
||||
id: sendContactRequestButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
objectName: "sendContactRequestButton"
|
||||
|
||||
visible: CurrentConversation.isTemporary || CurrentConversation.isBanned
|
||||
source: JamiResources.add_people_24dp_svg
|
||||
toolTipText: JamiStrings.addToConversations
|
||||
|
||||
onClicked: CurrentConversation.isBanned ?
|
||||
MessagesAdapter.unbanConversation(CurrentConversation.id) :
|
||||
MessagesAdapter.sendConversationRequest()
|
||||
onClicked: CurrentConversation.isBanned ? MessagesAdapter.unbanConversation(CurrentConversation.id) : MessagesAdapter.sendConversationRequest()
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
JamiPushButton {
|
||||
id: searchMessagesButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
objectName: "searchMessagesButton"
|
||||
|
||||
checkable: true
|
||||
checked: extrasPanel.isOpen(ChatView.MessagesResearchPanel)
|
||||
visible: root.swarmDetailsVisibility
|
||||
source: JamiResources.ic_baseline_search_24dp_svg
|
||||
source: JamiResources.ic_baseline_search_24dp_svg
|
||||
toolTipText: JamiStrings.search
|
||||
|
||||
onClicked: extrasPanel.switchToPanel(ChatView.MessagesResearchPanel)
|
||||
@ -224,8 +234,10 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
JamiPushButton { QWKSetParentHitTestVisible {}
|
||||
JamiPushButton {
|
||||
id: detailsButton
|
||||
QWKSetParentHitTestVisible {
|
||||
}
|
||||
objectName: "detailsButton"
|
||||
|
||||
checkable: true
|
||||
|
||||
@ -54,7 +54,7 @@ BaseModalDialog {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 35
|
||||
|
||||
placeHolderText: type === ContactList.TRANSFER ? JamiStrings.transferTo : JamiStrings.addParticipant
|
||||
placeHolderText: type === ContactList.TRANSFER ? JamiStrings.transferTo : JamiStrings.inviteMember
|
||||
|
||||
onSearchBarTextChanged: function(text){
|
||||
ContactAdapter.setSearchFilter(text);
|
||||
|
||||
138
src/app/mainview/components/ConversationPickerItemDelegate.qml
Normal file
138
src/app/mainview/components/ConversationPickerItemDelegate.qml
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Enums 1.1
|
||||
import net.jami.Models 1.1
|
||||
import "../../commoncomponents"
|
||||
|
||||
ItemDelegate {
|
||||
id: root
|
||||
|
||||
width: ListView.view.width
|
||||
height: JamiTheme.smartListItemHeight
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 15
|
||||
anchors.rightMargin: 15
|
||||
spacing: 10
|
||||
|
||||
ConversationAvatar {
|
||||
id: avatar
|
||||
objectName: "smartlistItemDelegateAvatar"
|
||||
|
||||
imageId: UID
|
||||
presenceStatus: Presence
|
||||
showPresenceIndicator: Presence !== undefined ? Presence : false
|
||||
|
||||
Layout.preferredWidth: JamiTheme.smartListAvatarSize
|
||||
Layout.preferredHeight: JamiTheme.smartListAvatarSize
|
||||
|
||||
Rectangle {
|
||||
id: overlayHighlighted
|
||||
visible: highlighted
|
||||
|
||||
anchors.fill: parent
|
||||
color: Qt.rgba(0, 0, 0, 0.5)
|
||||
radius: JamiTheme.smartListAvatarSize / 2
|
||||
|
||||
Image {
|
||||
id: highlightedImage
|
||||
|
||||
width: JamiTheme.smartListAvatarSize / 2
|
||||
height: JamiTheme.smartListAvatarSize / 2
|
||||
anchors.centerIn: parent
|
||||
|
||||
layer {
|
||||
enabled: true
|
||||
effect: ColorOverlay {
|
||||
color: "white"
|
||||
}
|
||||
}
|
||||
source: JamiResources.check_black_24dp_svg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: 0
|
||||
|
||||
// best name
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideMiddle
|
||||
text: Title === undefined ? "" : Title
|
||||
textFormat: TextEdit.PlainText
|
||||
font.pointSize: JamiTheme.mediumFontSize
|
||||
font.weight: UnreadMessagesCount ? Font.Bold : Font.Normal
|
||||
color: JamiTheme.textColor
|
||||
}
|
||||
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: JamiStrings.blocked
|
||||
textFormat: TextEdit.PlainText
|
||||
visible: IsBanned
|
||||
font.pointSize: JamiTheme.mediumFontSize
|
||||
font.weight: Font.Bold
|
||||
color: JamiTheme.textColor
|
||||
}
|
||||
}
|
||||
|
||||
Accessible.role: Accessible.Button
|
||||
Accessible.name: Title === undefined ? "" : Title
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: {
|
||||
if (root.pressed || root.highlighted)
|
||||
return JamiTheme.smartListSelectedColor;
|
||||
else if (root.hovered)
|
||||
return JamiTheme.smartListHoveredColor;
|
||||
else
|
||||
return "transparent";
|
||||
}
|
||||
}
|
||||
|
||||
highlighted: {
|
||||
return mainMenu.selectedUids.includes(UID);
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
const currentSelectedUids = mainMenu.selectedUids;
|
||||
if (currentSelectedUids.includes(UID)) {
|
||||
mainMenu.selectedUids = currentSelectedUids.filter(uid => uid !== UID);
|
||||
} else {
|
||||
mainMenu.selectedUids = currentSelectedUids.concat(UID);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -43,7 +43,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
property list<GeneralMenuItem> menuItems: [
|
||||
GeneralMenuItem {
|
||||
id: startVideoCallItem
|
||||
id: startVideoCall
|
||||
|
||||
canTrigger: CurrentAccount.videoEnabled_Video && !hasCall && !readOnly
|
||||
itemName: JamiStrings.startVideoCall
|
||||
|
||||
@ -60,7 +60,7 @@ JamiListView {
|
||||
|
||||
property var messageListModel: MessagesAdapter.mediaMessageListModel
|
||||
readonly property int documentType: Interaction.Type.DATA_TRANSFER
|
||||
readonly property int transferFinishedType: Interaction.Status.TRANSFER_FINISHED
|
||||
readonly property int transferFinishedType: Interaction.TransferStatus.TRANSFER_FINISHED
|
||||
readonly property int transferSuccesType: Interaction.Status.SUCCESS
|
||||
|
||||
onMessageListModelChanged: sourceModel = root.visible && messageListModel ? messageListModel : null
|
||||
|
||||
@ -28,7 +28,6 @@ Rectangle {
|
||||
property alias filesToSendListModel: repeater.model
|
||||
property alias filesToSendCount: repeater.count
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
|
||||
LayoutMirroring.enabled: UtilsAdapter.isRTL
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
@ -51,7 +50,7 @@ Rectangle {
|
||||
layoutDirection: UtilsAdapter.isRTL ? Qt.RightToLeft : Qt.LeftToRight
|
||||
|
||||
spacing: JamiTheme.filesToSendContainerSpacing
|
||||
padding: JamiTheme.filesToSendContainerPadding
|
||||
//padding: JamiTheme.filesToSendContainerPadding
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
@ -37,27 +37,27 @@ Window {
|
||||
id: keyboardGeneralShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl + J"
|
||||
shortcut: "Ctrl+J"
|
||||
description: qsTr("Open account list")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + L"
|
||||
shortcut: "Ctrl+L"
|
||||
description: qsTr("Focus conversations list")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + R"
|
||||
shortcut: "Ctrl+R"
|
||||
description: qsTr("Requests list")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + ↑"
|
||||
shortcut: "Ctrl+↑"
|
||||
description: qsTr("Previous conversation")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + ↓"
|
||||
shortcut: "Ctrl+↓"
|
||||
description: qsTr("Next conversation")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + F"
|
||||
shortcut: "Ctrl+F"
|
||||
description: qsTr("Search bar")
|
||||
}
|
||||
ListElement {
|
||||
@ -65,15 +65,15 @@ Window {
|
||||
description: qsTr("Full screen")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + +"
|
||||
shortcut: "Ctrl++"
|
||||
description: qsTr("Increase font size")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + -"
|
||||
shortcut: "Ctrl+-"
|
||||
description: qsTr("Decrease font size")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + 0"
|
||||
shortcut: "Ctrl+0"
|
||||
description: qsTr("Reset font size")
|
||||
}
|
||||
},
|
||||
@ -81,33 +81,13 @@ Window {
|
||||
id: keyboardConversationShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + C"
|
||||
description: qsTr("Start an audio call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + X"
|
||||
description: qsTr("Start a video call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + L"
|
||||
description: qsTr("Clear history")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + F"
|
||||
description: qsTr("Search messages/files")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + B"
|
||||
description: qsTr("Block contact")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + Delete"
|
||||
description: qsTr("Remove conversation")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + A"
|
||||
shortcut: "Ctrl+Shift+A"
|
||||
description: qsTr("Accept contact request")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+Shift+F"
|
||||
description: qsTr("Search messages/files")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "↑"
|
||||
description: qsTr("Edit last message")
|
||||
@ -116,50 +96,41 @@ Window {
|
||||
shortcut: "Esc"
|
||||
description: qsTr("Cancel message edition")
|
||||
}
|
||||
},
|
||||
ListModel {
|
||||
id: keyboardSettingsShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl + M"
|
||||
description: qsTr("Media settings")
|
||||
shortcut: "Ctrl+Shift+L"
|
||||
description: qsTr("Clear history")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + G"
|
||||
description: qsTr("General settings")
|
||||
shortcut: "Ctrl+Shift+B"
|
||||
description: qsTr("Block contact")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Alt + I"
|
||||
description: qsTr("Account settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + P"
|
||||
description: qsTr("Plugin settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + N"
|
||||
description: qsTr("Open account creation wizard")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "F10"
|
||||
shortcut2: ""
|
||||
description: qsTr("Open keyboard shortcut table")
|
||||
shortcut: "Ctrl+Shift+Delete"
|
||||
description: qsTr("Leave conversation")
|
||||
}
|
||||
},
|
||||
ListModel {
|
||||
id: keyboardCallsShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Y"
|
||||
description: qsTr("Answer an incoming call")
|
||||
shortcut: "Ctrl+Shift+C"
|
||||
description: qsTr("Start audio call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + D"
|
||||
shortcut: "Ctrl+Shift+X"
|
||||
description: qsTr("Start video call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+Y"
|
||||
description: qsTr("Answer incoming call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+D"
|
||||
description: qsTr("End call")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Shift + D"
|
||||
description: qsTr("Decline the call request")
|
||||
shortcut: "Ctrl+Shift+D"
|
||||
description: qsTr("Decline call request")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "M"
|
||||
@ -170,7 +141,7 @@ Window {
|
||||
description: qsTr("Stop camera")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Mouse middle click"
|
||||
shortcut: "Ctrl+Mouse middle click"
|
||||
description: qsTr("Take tile screenshot")
|
||||
}
|
||||
},
|
||||
@ -178,48 +149,77 @@ Window {
|
||||
id: keyboardMarkdownShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl + B"
|
||||
shortcut: "Ctrl+B"
|
||||
description: qsTr("Bold")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + I"
|
||||
shortcut: "Ctrl+I"
|
||||
description: qsTr("Italic")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + X"
|
||||
shortcut: "Shift+Alt+X"
|
||||
description: qsTr("Strikethrough")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Alt + H"
|
||||
shortcut: "Ctrl+Alt+H"
|
||||
description: qsTr("Heading")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Alt + K"
|
||||
shortcut: "Ctrl+Alt+K"
|
||||
description: qsTr("Link")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl + Alt + C"
|
||||
shortcut: "Ctrl+Alt+C"
|
||||
description: qsTr("Code")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + 9"
|
||||
shortcut: "Shift+Alt+9"
|
||||
description: qsTr("Quote")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + 8"
|
||||
shortcut: "Shift+Alt+8"
|
||||
description: qsTr("Unordered list")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + 7"
|
||||
shortcut: "Shift+Alt+7"
|
||||
description: qsTr("Ordered list")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + T"
|
||||
description: qsTr("Show formatting")
|
||||
shortcut: "Shift+Alt+T"
|
||||
description: qsTr("Show/hide formatting")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Shift + Alt + P"
|
||||
description: qsTr("Show preview")
|
||||
shortcut: "Shift+Alt+P"
|
||||
description: qsTr("Show preview/Continue editing")
|
||||
}
|
||||
},
|
||||
ListModel {
|
||||
id: keyboardSettingsShortcutsModel
|
||||
|
||||
ListElement {
|
||||
shortcut: "Ctrl+Alt+I"
|
||||
description: qsTr("Open account settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+G"
|
||||
description: qsTr("Open general settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+M"
|
||||
description: qsTr("Open media settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+E"
|
||||
description: qsTr("Open extensions settings")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "Ctrl+Shift+N"
|
||||
description: qsTr("Open account creation wizard")
|
||||
}
|
||||
ListElement {
|
||||
shortcut: "F10"
|
||||
shortcut2: ""
|
||||
description: qsTr("View keyboard shortcuts")
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -302,7 +302,7 @@ Window {
|
||||
focus: true
|
||||
|
||||
Repeater {
|
||||
model: [JamiStrings.generalSettingsTitle, JamiStrings.conversationKeyboardShortcuts, JamiStrings.callKeyboardShortcuts, JamiStrings.settings, JamiStrings.markdownKeyboardShortcuts]
|
||||
model: [JamiStrings.generalSettingsTitle, JamiStrings.conversationKeyboardShortcuts, JamiStrings.callKeyboardShortcuts, JamiStrings.markdownKeyboardShortcuts, JamiStrings.settings]
|
||||
|
||||
TabButton {
|
||||
id: tabButton
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -17,23 +17,20 @@
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Enums 1.1
|
||||
import net.jami.Models 1.1
|
||||
import "../../commoncomponents"
|
||||
import QtQuick.Layouts
|
||||
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
JamiFlickable {
|
||||
id: root
|
||||
|
||||
property int maxWidth: 330
|
||||
property bool tooMuch: {
|
||||
if (maxWidth > 0)
|
||||
return textArea.contentWidth > maxWidth;
|
||||
return false;
|
||||
}
|
||||
property alias text: textArea.text
|
||||
property var textAreaObj: textArea
|
||||
property alias placeholderText: textArea.placeholderText
|
||||
@ -42,16 +39,15 @@ JamiFlickable {
|
||||
property alias selectionEnd: textArea.selectionEnd
|
||||
property bool showPreview: false
|
||||
property bool isShowTypo: UtilsAdapter.getAppValue(Settings.Key.ShowMardownOption)
|
||||
property int textWidth: textArea.contentWidth
|
||||
|
||||
ScrollBar.vertical.visible: textArea.text
|
||||
ScrollBar.horizontal.visible: textArea.text
|
||||
// Used to cache the editable text when showing the preview message
|
||||
// and also to debounce the textChanged signal's effect on the composing status.
|
||||
property string cachedText
|
||||
property string debounceText
|
||||
|
||||
signal sendMessagesRequired
|
||||
|
||||
function heightBinding() {
|
||||
textArea.height = Qt.binding(() => textArea.lineCount === 1 ? 35 : textArea.paintedHeight);
|
||||
}
|
||||
|
||||
function selectText(start, end) {
|
||||
textArea.select(start, end);
|
||||
}
|
||||
@ -60,18 +56,18 @@ JamiFlickable {
|
||||
textArea.insert(textArea.cursorPosition, text);
|
||||
}
|
||||
|
||||
function clearText() {
|
||||
var multiLine = textArea.lineCount !== 1;
|
||||
textArea.clear();
|
||||
if (multiLine) {
|
||||
heightBinding();
|
||||
}
|
||||
}
|
||||
|
||||
function pasteText() {
|
||||
textArea.paste();
|
||||
}
|
||||
|
||||
function clearText() {
|
||||
textArea.clear();
|
||||
}
|
||||
|
||||
function restoreVisibilityAfterSend() {
|
||||
showPreview = false;
|
||||
}
|
||||
|
||||
LineEditContextMenu {
|
||||
id: textAreaContextMenu
|
||||
|
||||
@ -84,94 +80,55 @@ JamiFlickable {
|
||||
}
|
||||
}
|
||||
|
||||
interactive: true
|
||||
attachedFlickableMoving: textAreaPreview.height > height || textArea.height > height || root.moving
|
||||
ScrollBar.vertical.visible: text
|
||||
ScrollBar.horizontal.visible: text
|
||||
|
||||
contentHeight: showPreview ? textAreaPreview.height : textArea.height
|
||||
boundsMovement: Flickable.StopAtBounds
|
||||
boundsBehavior: Flickable.DragOverBounds
|
||||
interactive: true
|
||||
|
||||
function resetEditableText() {
|
||||
textArea.text = cachedText;
|
||||
textArea.update();
|
||||
}
|
||||
|
||||
onShowPreviewChanged: {
|
||||
if (showPreview) {
|
||||
textAreaPreview.height = textArea.lineCount === 1 ? textArea.height : textAreaPreview.paintedHeight;
|
||||
cachedText = textArea.text;
|
||||
MessagesAdapter.parseMessage("", textArea.text, false, "", "");
|
||||
} else {
|
||||
textArea.textFormatChanged.disconnect(resetEditableText);
|
||||
textArea.textFormatChanged.connect(resetEditableText);
|
||||
}
|
||||
heightBinding();
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: textAreaPreview
|
||||
|
||||
onWidthChanged: root.height = this.height
|
||||
|
||||
overwriteMode: false
|
||||
readOnly: true
|
||||
|
||||
height: textArea.lineCount === 1 ? textArea.height : this.paintedHeight
|
||||
width: textArea.width
|
||||
|
||||
visible: showPreview
|
||||
leftPadding: JamiTheme.scrollBarHandleSize
|
||||
rightPadding: JamiTheme.scrollBarHandleSize
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
Connections {
|
||||
target: textArea
|
||||
function onTextChanged() {
|
||||
MessagesAdapter.parseMessage("", textArea.text, false, "", "");
|
||||
Connections {
|
||||
target: MessagesAdapter
|
||||
function onMessageParsed(messageId, messageText) {
|
||||
if (messageId === "") {
|
||||
textArea.text = messageText;
|
||||
textArea.update();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: MessagesAdapter
|
||||
function onMessageParsed(messageId, messageText) {
|
||||
if (messageId === "") {
|
||||
textAreaPreview.text = messageText;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize + 2
|
||||
font.hintingPreference: Font.PreferNoHinting
|
||||
|
||||
color: JamiTheme.textColor
|
||||
wrapMode: TextEdit.Wrap
|
||||
textFormat: TextEdit.RichText
|
||||
placeholderTextColor: JamiTheme.messageBarPlaceholderTextColor
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
|
||||
background: Rectangle {
|
||||
border.width: 0
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
||||
|
||||
TextArea.flickable: TextArea {
|
||||
id: textArea
|
||||
|
||||
visible: !showPreview
|
||||
|
||||
readOnly: showPreview
|
||||
leftPadding: JamiTheme.scrollBarHandleSize
|
||||
rightPadding: JamiTheme.scrollBarHandleSize
|
||||
topPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
persistentSelection: true
|
||||
|
||||
height: textArea.lineCount === 1 ? 35 : textArea.paintedHeight
|
||||
|
||||
verticalAlignment: TextEdit.AlignVCenter
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize + 2
|
||||
font.hintingPreference: Font.PreferNoHinting
|
||||
|
||||
color: JamiTheme.textColor
|
||||
wrapMode: TextEdit.Wrap
|
||||
selectByMouse: true
|
||||
textFormat: TextEdit.PlainText
|
||||
selectByMouse: !showPreview
|
||||
textFormat: showPreview ? TextEdit.RichText : TextEdit.PlainText
|
||||
|
||||
placeholderTextColor: JamiTheme.messageBarPlaceholderTextColor
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
property var cacheText: ""
|
||||
|
||||
background: Rectangle {
|
||||
border.width: 0
|
||||
@ -184,8 +141,8 @@ JamiFlickable {
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
if (text != cacheText) {
|
||||
cacheText = text;
|
||||
if (text !== debounceText && !showPreview) {
|
||||
debounceText = text;
|
||||
MessagesAdapter.userIsComposing(text ? true : false);
|
||||
}
|
||||
}
|
||||
|
||||
693
src/app/mainview/components/MessageFormatBar.qml
Normal file
693
src/app/mainview/components/MessageFormatBar.qml
Normal file
@ -0,0 +1,693 @@
|
||||
/*
|
||||
* 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
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
import SortFilterProxyModel 0.2
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Enums 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import "../../commoncomponents"
|
||||
import "qrc:/js/markdownedition.js" as MDE
|
||||
|
||||
Rectangle {
|
||||
id: messageBarRowLayout
|
||||
Layout.preferredWidth: showTypo ? firstRow.width + secondRow.width : secondRow.width
|
||||
LayoutMirroring.enabled: UtilsAdapter.isRTL
|
||||
LayoutMirroring.childrenInherit: true
|
||||
|
||||
Row {
|
||||
id: firstRow
|
||||
anchors.left: messageBarRowLayout.left
|
||||
anchors.bottom: messageBarRowLayout.bottom
|
||||
|
||||
Row {
|
||||
id: listViewTypo
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
|
||||
ListView {
|
||||
id: listViewTypoFirst
|
||||
objectName: "listViewTypoFirst"
|
||||
|
||||
visible: showTypo
|
||||
width: visible ? contentWidth + 2 * leftMargin : 0
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: JamiTheme.longFadeDuration / 2
|
||||
}
|
||||
}
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
|
||||
property list<Action> menuTypoActionsFirst: [
|
||||
Action {
|
||||
id: boldAction
|
||||
property string iconSrc: JamiResources.bold_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.bold
|
||||
property string shortcutKey: "Ctrl+B"
|
||||
property bool isStyle: MDE.isStyle(messageBarTextArea, rectangle.text, "**", "**")
|
||||
onTriggered: MDE.addStyle(messageBarTextArea, rectangle.text, "**", "**")
|
||||
},
|
||||
Action {
|
||||
id: italicAction
|
||||
property string iconSrc: JamiResources.italic_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.italic
|
||||
property string shortcutKey: "Ctrl+I"
|
||||
property bool isStyle: MDE.isStyle(messageBarTextArea, rectangle.text, "*", "*")
|
||||
onTriggered: MDE.addStyle(messageBarTextArea, rectangle.text, "*", "*")
|
||||
},
|
||||
Action {
|
||||
id: strikethroughAction
|
||||
property string iconSrc: JamiResources.s_barre_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.strikethrough
|
||||
property string shortcutKey: "Shift+Alt+X"
|
||||
property bool isStyle: MDE.isStyle(messageBarTextArea, rectangle.text, "~~", "~~")
|
||||
onTriggered: MDE.addStyle(messageBarTextArea, rectangle.text, "~~", "~~")
|
||||
},
|
||||
Action {
|
||||
id: titleAction
|
||||
property string iconSrc: JamiResources.title_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.heading
|
||||
property string shortcutKey: "Ctrl+Alt+H"
|
||||
property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, rectangle.text, "### ", false)
|
||||
onTriggered: MDE.addPrefixStyle(messageBarTextArea, rectangle.text, "### ", false)
|
||||
},
|
||||
Action {
|
||||
id: linkAction
|
||||
property string iconSrc: JamiResources.link_web_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.link
|
||||
property string shortcutKey: "Ctrl+Alt+K"
|
||||
property bool isStyle: MDE.isStyle(messageBarTextArea, rectangle.text, "[", "](url)")
|
||||
onTriggered: MDE.addStyle(messageBarTextArea, rectangle.text, "[", "](url)")
|
||||
},
|
||||
Action {
|
||||
id: codeAction
|
||||
property string iconSrc: JamiResources.code_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.code
|
||||
property string shortcutKey: "Ctrl+Alt+C"
|
||||
property bool isStyle: MDE.isStyle(messageBarTextArea, rectangle.text, "```", "```")
|
||||
onTriggered: MDE.addStyle(messageBarTextArea, rectangle.text, "```", "```")
|
||||
}
|
||||
]
|
||||
|
||||
model: menuTypoActionsFirst
|
||||
|
||||
delegate: PushButton {
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
preferredSize: JamiTheme.chatViewFooterButtonSize
|
||||
imageContainerWidth: 15
|
||||
imageContainerHeight: 15
|
||||
radius: 5
|
||||
|
||||
hoverEnabled: !showPreview
|
||||
enabled: !showPreview
|
||||
|
||||
toolTipText: modelData.shortcutText
|
||||
shortcutKey: modelData.shortcutKey
|
||||
hasShortcut: true
|
||||
|
||||
source: modelData.iconSrc
|
||||
focusPolicy: Qt.TabFocus
|
||||
|
||||
normalColor: {
|
||||
if (showPreview) {
|
||||
return JamiTheme.primaryBackgroundColor;
|
||||
} else if (modelData.isStyle) {
|
||||
return JamiTheme.hoveredButtonColor;
|
||||
} else {
|
||||
return JamiTheme.primaryBackgroundColor;
|
||||
}
|
||||
}
|
||||
imageColor: {
|
||||
if (showPreview) {
|
||||
return JamiTheme.chatViewFooterImgDisableColor;
|
||||
} else if (hovered) {
|
||||
return JamiTheme.chatViewFooterImgHoverColor;
|
||||
} else if (modelData.isStyle) {
|
||||
return JamiTheme.chatViewFooterImgHoverColor;
|
||||
} else {
|
||||
return JamiTheme.chatViewFooterImgColor;
|
||||
}
|
||||
}
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
|
||||
action: modelData
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
visible: showTypo && showTypoSecond
|
||||
width: 5
|
||||
|
||||
Rectangle {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: 1
|
||||
height: JamiTheme.chatViewFooterButtonSize * 2 / 3
|
||||
color: showPreview ? JamiTheme.chatViewFooterImgDisableColor : JamiTheme.chatViewFooterSeparateLineColor
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
z: -1
|
||||
radius: 0
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
|
||||
visible: showTypo && !showTypoSecond
|
||||
|
||||
ComboBox {
|
||||
id: showMoreTypoButton
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
height: width
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
enabled: !showPreview
|
||||
hoverEnabled: !showPreview
|
||||
|
||||
MaterialToolTip {
|
||||
id: toolTip
|
||||
parent: showMoreTypoButton
|
||||
visible: showMoreTypoButton.hovered && (text.length > 0)
|
||||
delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
text: markdownPopup.visible ? JamiStrings.showLess : JamiStrings.showMore
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: showMoreTypoButton.width
|
||||
implicitHeight: showMoreTypoButton.height
|
||||
radius: 5
|
||||
color: showPreview ? JamiTheme.transparentColor : (parent && parent.hovered ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor)
|
||||
}
|
||||
|
||||
indicator: ResponsiveImage {
|
||||
containerHeight: 20
|
||||
containerWidth: 20
|
||||
width: 18
|
||||
height: 18
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
source: JamiResources.more_vert_24dp_svg
|
||||
|
||||
color: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (parent && parent.hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
|
||||
}
|
||||
|
||||
popup: MarkdownPopup {
|
||||
id: markdownPopup
|
||||
y: 1.5 * parent.height
|
||||
x: -parent.width * 2
|
||||
width: listViewTypoSecond.width + 10
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
|
||||
menuTypoActionsSecond: listViewTypoSecond.menuTypoActionsSecond
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listViewTypoSecond
|
||||
visible: showTypo && showTypoSecond
|
||||
width: contentWidth + 2 * leftMargin
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: JamiTheme.transparentColor
|
||||
z: -1
|
||||
}
|
||||
|
||||
property list<Action> menuTypoActionsSecond: [
|
||||
Action {
|
||||
id: quoteAction
|
||||
property string iconSrc: JamiResources.quote_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.quote
|
||||
property string shortcutKey: "Shift+Alt+9"
|
||||
property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, rectangle.text, "> ", false)
|
||||
onTriggered: MDE.addPrefixStyle(messageBarTextArea, rectangle.text, "> ", false)
|
||||
},
|
||||
Action {
|
||||
id: unorderedListAction
|
||||
property string iconSrc: JamiResources.bullet_point_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.unorderedList
|
||||
property string shortcutKey: "Shift+Alt+8"
|
||||
property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, rectangle.text, "- ", false)
|
||||
onTriggered: MDE.addPrefixStyle(messageBarTextArea, rectangle.text, "- ", false)
|
||||
},
|
||||
Action {
|
||||
id: orderedListAction
|
||||
property string iconSrc: JamiResources.bullet_number_black_24dp_svg
|
||||
property string shortcutText: JamiStrings.orderedList
|
||||
property string shortcutKey: "Shift+Alt+7"
|
||||
property bool isStyle: MDE.isPrefixSyle(messageBarTextArea, rectangle.text, "", true)
|
||||
onTriggered: MDE.addPrefixStyle(messageBarTextArea, rectangle.text, "", true)
|
||||
}
|
||||
]
|
||||
|
||||
model: menuTypoActionsSecond
|
||||
|
||||
delegate: PushButton {
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
preferredSize: JamiTheme.chatViewFooterButtonSize
|
||||
imageContainerWidth: 20
|
||||
imageContainerHeight: 20
|
||||
radius: 5
|
||||
|
||||
hoverEnabled: !showPreview
|
||||
enabled: !showPreview
|
||||
|
||||
toolTipText: modelData.shortcutText
|
||||
shortcutKey: modelData.shortcutKey
|
||||
hasShortcut: modelData.hasShortcut ? true : false
|
||||
source: modelData.iconSrc
|
||||
focusPolicy: Qt.TabFocus
|
||||
|
||||
normalColor: {
|
||||
if (showPreview) {
|
||||
return JamiTheme.primaryBackgroundColor;
|
||||
} else if (modelData.normalColor) {
|
||||
return modelData.normalColor;
|
||||
} else if (modelData.isStyle) {
|
||||
return JamiTheme.hoveredButtonColor;
|
||||
} else {
|
||||
return JamiTheme.primaryBackgroundColor;
|
||||
}
|
||||
}
|
||||
imageColor: {
|
||||
if (showPreview) {
|
||||
return JamiTheme.chatViewFooterImgDisableColor;
|
||||
} else if (hovered) {
|
||||
return JamiTheme.chatViewFooterImgHoverColor;
|
||||
} else if (modelData.isStyle) {
|
||||
return JamiTheme.chatViewFooterImgHoverColor;
|
||||
} else {
|
||||
return JamiTheme.chatViewFooterImgColor;
|
||||
}
|
||||
}
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
|
||||
action: modelData
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: secondRow
|
||||
anchors.right: messageBarRowLayout.right
|
||||
anchors.bottom: messageBarRowLayout.bottom
|
||||
|
||||
PushButton {
|
||||
id: typoButton
|
||||
|
||||
preferredSize: JamiTheme.chatViewFooterButtonSize
|
||||
imageContainerWidth: 24
|
||||
imageContainerHeight: 24
|
||||
|
||||
radius: JamiTheme.chatViewFooterButtonRadius
|
||||
|
||||
hoverEnabled: !showPreview
|
||||
enabled: !showPreview
|
||||
|
||||
toolTipText: showTypo ? JamiStrings.hideFormatting : JamiStrings.showFormatting
|
||||
source: JamiResources.text_edit_black_24dp_svg
|
||||
|
||||
normalColor: showPreview ? JamiTheme.primaryBackgroundColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor)
|
||||
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered || showTypo ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
|
||||
onClicked: {
|
||||
showTypo = !showTypo;
|
||||
messageBarTextArea.isShowTypo = showTypo;
|
||||
if (messageBar.width < messageBarLayoutMaximumWidth + sendMessageButton.width + 2 * JamiTheme.preferredMarginSize)
|
||||
showTypoSecond = false;
|
||||
if (!showDefault)
|
||||
showDefault = true;
|
||||
UtilsAdapter.setAppValue(Settings.Key.ShowMardownOption, showTypo);
|
||||
UtilsAdapter.setAppValue(Settings.Key.ShowSendOption, !showDefault);
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listViewMoreButton
|
||||
|
||||
width: 0
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: JamiTheme.longFadeDuration / 2
|
||||
}
|
||||
}
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
|
||||
leftMargin: 10
|
||||
rightMargin: 10
|
||||
property list<Action> menuMoreButton: [
|
||||
Action {
|
||||
id: leaveAudioMessage
|
||||
property string iconSrc: JamiResources.message_audio_black_24dp_svg
|
||||
property string toolTip: JamiStrings.leaveAudioMessage
|
||||
property bool show: false
|
||||
property bool needWebEngine: false
|
||||
property bool needVideoDevice: false
|
||||
property bool noSip: false
|
||||
onTriggered: function clickAction() {
|
||||
audioRecordMessageButtonClicked();
|
||||
}
|
||||
},
|
||||
Action {
|
||||
id: leaveVideoMessage
|
||||
property string iconSrc: JamiResources.message_video_black_24dp_svg
|
||||
property string toolTip: JamiStrings.leaveVideoMessage
|
||||
property bool show: false
|
||||
property bool needWebEngine: false
|
||||
property bool needVideoDevice: true
|
||||
property bool noSip: false
|
||||
onTriggered: function clickAction() {
|
||||
videoRecordMessageButtonClicked();
|
||||
}
|
||||
},
|
||||
Action {
|
||||
id: shareLocation
|
||||
property string iconSrc: JamiResources.localisation_sharing_send_pin_svg
|
||||
property string toolTip: JamiStrings.shareLocation
|
||||
property bool show: false
|
||||
property bool needWebEngine: true
|
||||
property bool needVideoDevice: false
|
||||
property bool noSip: false
|
||||
onTriggered: function clickAction() {
|
||||
showMapClicked();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
ListModel {
|
||||
id: listMoreButton
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < listViewMoreButton.menuMoreButton.length; i++) {
|
||||
append({
|
||||
"menuAction": listViewMoreButton.menuMoreButton[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: listMoreButton
|
||||
filters: [
|
||||
ExpressionFilter {
|
||||
expression: menuAction.show === true
|
||||
enabled: showDefault
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.needWebEngine === false
|
||||
enabled: !WITH_WEBENGINE
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.noSip === true
|
||||
enabled: CurrentConversation.isSip
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.needVideoDevice === false
|
||||
enabled: VideoDevices.listSize === 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
delegate: PushButton {
|
||||
id: buttonDelegateMoreButton
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
preferredSize: JamiTheme.chatViewFooterButtonSize
|
||||
imageContainerWidth: 20
|
||||
imageContainerHeight: 20
|
||||
radius: 5
|
||||
enabled: !showPreview
|
||||
hoverEnabled: !showPreview
|
||||
toolTipText: modelData.toolTip
|
||||
source: modelData.iconSrc
|
||||
|
||||
normalColor: showPreview ? JamiTheme.primaryBackgroundColor : (showTypo ? JamiTheme.hoveredButtonColor : JamiTheme.primaryBackgroundColor)
|
||||
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
action: modelData
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
Layout.alignment: Qt.AlignRight
|
||||
visible: !CurrentConversation.isSip
|
||||
color: JamiTheme.transparentColor
|
||||
ComboBox {
|
||||
id: showMoreButton
|
||||
focus: true
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
anchors.bottom: parent.bottom
|
||||
enabled: !showPreview
|
||||
hoverEnabled: !showPreview
|
||||
|
||||
// Used to choose the correct color for the button.
|
||||
readonly property bool highlight: down || hovered
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: showMoreButton.width
|
||||
implicitHeight: showMoreButton.height
|
||||
radius: 5
|
||||
color: showMoreButton.highlight ? JamiTheme.hoveredButtonColor : JamiTheme.transparentColor
|
||||
}
|
||||
|
||||
MaterialToolTip {
|
||||
id: toolTipMoreButton
|
||||
|
||||
parent: showMoreButton
|
||||
visible: showMoreButton.hovered && (text.length > 0)
|
||||
delay: Qt.styleHints.mousePressAndHoldInterval
|
||||
text: showMoreButton.down ? JamiStrings.showLess : JamiStrings.showMore
|
||||
}
|
||||
|
||||
indicator: ResponsiveImage {
|
||||
|
||||
width: 20
|
||||
height: 20
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
source: JamiResources.more_menu_black_24dp_svg
|
||||
|
||||
color: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
|
||||
}
|
||||
|
||||
Component {
|
||||
id: sharePopupComp
|
||||
ShareMenu {
|
||||
id: sharePopup
|
||||
onAudioRecordMessageButtonClicked: rectangle.audioRecordMessageButtonClicked()
|
||||
onVideoRecordMessageButtonClicked: rectangle.videoRecordMessageButtonClicked()
|
||||
onShowMapClicked: rectangle.showMapClicked()
|
||||
modelList: listViewMoreButton.menuMoreButton
|
||||
y: showMoreButton.y + 31
|
||||
x: showMoreButton.x - 3
|
||||
}
|
||||
}
|
||||
|
||||
popup: ShareMenu {
|
||||
id: sharePopup
|
||||
onAudioRecordMessageButtonClicked: rectangle.audioRecordMessageButtonClicked()
|
||||
onVideoRecordMessageButtonClicked: rectangle.videoRecordMessageButtonClicked()
|
||||
onShowMapClicked: rectangle.showMapClicked()
|
||||
modelList: listViewMoreButton.menuMoreButton
|
||||
y: showMoreButton.y + 31
|
||||
x: showMoreButton.x - 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: listViewAction
|
||||
|
||||
width: contentWidth + 2 * leftMargin
|
||||
|
||||
Behavior on width {
|
||||
NumberAnimation {
|
||||
duration: JamiTheme.longFadeDuration / 2
|
||||
}
|
||||
}
|
||||
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
orientation: ListView.Horizontal
|
||||
interactive: false
|
||||
|
||||
property list<Action> menuActions: [
|
||||
Action {
|
||||
id: sendFile
|
||||
property string iconSrc: JamiResources.link_black_24dp_svg
|
||||
property string toolTip: JamiStrings.sendFile
|
||||
property bool show: true
|
||||
property bool needWebEngine: false
|
||||
property bool needVideoDevice: false
|
||||
property bool noSip: false
|
||||
onTriggered: function clickAction() {
|
||||
sendFileButtonClicked();
|
||||
textAreaObj.forceActiveFocus();
|
||||
}
|
||||
},
|
||||
Action {
|
||||
id: addEmoji
|
||||
property string iconSrc: JamiResources.emoji_black_24dp_svg
|
||||
property string toolTip: JamiStrings.addEmoji
|
||||
property bool show: true
|
||||
property bool needWebEngine: true
|
||||
property bool needVideoDevice: false
|
||||
property bool noSip: true
|
||||
onTriggered: function clickAction() {
|
||||
emojiButtonClicked();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
ListModel {
|
||||
id: listActions
|
||||
Component.onCompleted: {
|
||||
for (var i = 0; i < listViewAction.menuActions.length; i++) {
|
||||
append({
|
||||
"menuAction": listViewAction.menuActions[i]
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
sourceModel: listActions
|
||||
filters: [
|
||||
ExpressionFilter {
|
||||
expression: menuAction.show === true
|
||||
enabled: rectangle.showDefault
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.needWebEngine === false
|
||||
enabled: !WITH_WEBENGINE
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.noSip === true
|
||||
enabled: CurrentConversation.isSip
|
||||
},
|
||||
ExpressionFilter {
|
||||
expression: menuAction.needVideoDevice === false
|
||||
enabled: VideoDevices.listSize === 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
delegate: PushButton {
|
||||
id: buttonDelegate
|
||||
anchors.verticalCenter: parent ? parent.verticalCenter : undefined
|
||||
preferredSize: JamiTheme.chatViewFooterButtonSize
|
||||
imageContainerWidth: 25
|
||||
imageContainerHeight: 25
|
||||
radius: 5
|
||||
|
||||
hoverEnabled: !showPreview
|
||||
enabled: !showPreview
|
||||
|
||||
toolTipText: modelData.toolTip
|
||||
source: modelData.iconSrc
|
||||
|
||||
normalColor: JamiTheme.primaryBackgroundColor
|
||||
imageColor: showPreview ? JamiTheme.chatViewFooterImgDisableColor : (hovered ? JamiTheme.chatViewFooterImgHoverColor : JamiTheme.chatViewFooterImgColor)
|
||||
hoveredColor: JamiTheme.hoveredButtonColor
|
||||
pressedColor: hoveredColor
|
||||
|
||||
action: modelData
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
width: JamiTheme.chatViewFooterButtonSize
|
||||
Layout.rightMargin: marginSize / 2
|
||||
visible: true
|
||||
color: JamiTheme.transparentColor
|
||||
|
||||
PushButton {
|
||||
id: sendMessageButton
|
||||
|
||||
objectName: "sendMessageButton"
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
enabled: sendButtonVisibility
|
||||
hoverEnabled: enabled
|
||||
|
||||
width: scale * JamiTheme.chatViewFooterButtonSize
|
||||
height: JamiTheme.chatViewFooterButtonSize
|
||||
|
||||
radius: JamiTheme.chatViewFooterButtonRadius
|
||||
preferredSize: JamiTheme.chatViewFooterButtonIconSize - 6
|
||||
imageContainerWidth: 25
|
||||
imageContainerHeight: 25
|
||||
|
||||
toolTipText: JamiStrings.send
|
||||
|
||||
mirror: UtilsAdapter.isRTL
|
||||
|
||||
source: JamiResources.send_black_24dp_svg
|
||||
|
||||
normalColor: enabled ? JamiTheme.chatViewFooterSendButtonColor : JamiTheme.chatViewFooterSendButtonDisableColor
|
||||
imageColor: enabled ? JamiTheme.chatViewFooterSendButtonImgColor : JamiTheme.chatViewFooterSendButtonImgColorDisable
|
||||
hoveredColor: JamiTheme.buttonTintedBlueHovered
|
||||
pressedColor: hoveredColor
|
||||
|
||||
opacity: 1
|
||||
scale: opacity
|
||||
|
||||
Behavior on opacity {
|
||||
enabled: animate
|
||||
NumberAnimation {
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
rectangle.showPreview = false;
|
||||
sendMessageButtonClicked();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,40 +19,37 @@ import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt.labs.qmlmodels
|
||||
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
JamiListView {
|
||||
id: root
|
||||
|
||||
function getDistanceToBottom() {
|
||||
const scrollDiff = ScrollBar.vertical.position -
|
||||
(1.0 - ScrollBar.vertical.size)
|
||||
return Math.abs(scrollDiff) * contentHeight
|
||||
const scrollDiff = ScrollBar.vertical.position - (1.0 - ScrollBar.vertical.size);
|
||||
return Math.abs(scrollDiff) * contentHeight;
|
||||
}
|
||||
|
||||
function loadMoreMsgsIfNeeded() {
|
||||
if (atYBeginning && !CurrentConversation.allMessagesLoaded) {
|
||||
MessagesAdapter.loadMoreMessages()
|
||||
MessagesAdapter.loadMoreMessages();
|
||||
}
|
||||
}
|
||||
|
||||
function computeTimestampVisibility(item1, item1Index, item2, item2Index) {
|
||||
if (item1 && item2) {
|
||||
if (item1Index < item2Index) {
|
||||
item1.showTime = item1.timestamp - item2.timestamp > JamiTheme.timestampIntervalTime
|
||||
item1.showDay = item1.formattedDay !== item2.formattedDay
|
||||
item1.showTime = item1.timestamp - item2.timestamp > JamiTheme.timestampIntervalTime;
|
||||
item1.showDay = item1.formattedDay !== item2.formattedDay;
|
||||
} else {
|
||||
item2.showTime = item2.timestamp - item1.timestamp > JamiTheme.timestampIntervalTime
|
||||
item2.showDay = item2.formattedDay !== item1.formattedDay
|
||||
item2.showTime = item2.timestamp - item1.timestamp > JamiTheme.timestampIntervalTime;
|
||||
item2.showDay = item2.formattedDay !== item1.formattedDay;
|
||||
}
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
function scrollToBottom() {
|
||||
@ -60,27 +57,28 @@ JamiListView {
|
||||
}
|
||||
|
||||
function computeChatview(item, itemIndex) {
|
||||
if (!root) return
|
||||
var rootItem = root.itemAtIndex(0)
|
||||
var pItem = root.itemAtIndex(itemIndex - 1)
|
||||
var pItemIndex = itemIndex - 1
|
||||
var nItem = root.itemAtIndex(itemIndex + 1)
|
||||
var nItemIndex = itemIndex + 1
|
||||
if (!root)
|
||||
return;
|
||||
var rootItem = root.itemAtIndex(0);
|
||||
var pItem = root.itemAtIndex(itemIndex - 1);
|
||||
var pItemIndex = itemIndex - 1;
|
||||
var nItem = root.itemAtIndex(itemIndex + 1);
|
||||
var nItemIndex = itemIndex + 1;
|
||||
|
||||
// middle insertion
|
||||
if (pItem && nItem) {
|
||||
computeTimestampVisibility(item, itemIndex, nItem, nItemIndex)
|
||||
computeSequencing(item, nItem, root.itemAtIndex(itemIndex + 2))
|
||||
computeTimestampVisibility(item, itemIndex, nItem, nItemIndex);
|
||||
computeSequencing(item, nItem, root.itemAtIndex(itemIndex + 2));
|
||||
}
|
||||
// top buffer insertion = scroll up
|
||||
if (pItem && !nItem) {
|
||||
computeTimestampVisibility(item, itemIndex, pItem, pItemIndex)
|
||||
computeSequencing(root.itemAtIndex(itemIndex - 2), pItem, item)
|
||||
computeTimestampVisibility(item, itemIndex, pItem, pItemIndex);
|
||||
computeSequencing(root.itemAtIndex(itemIndex - 2), pItem, item);
|
||||
}
|
||||
// bottom buffer insertion = scroll down
|
||||
if (!pItem && nItem) {
|
||||
computeTimestampVisibility(item, itemIndex, nItem, nItemIndex)
|
||||
computeSequencing(item, nItem, root.itemAtIndex(itemIndex + 2))
|
||||
computeTimestampVisibility(item, itemIndex, nItem, nItemIndex);
|
||||
computeSequencing(item, nItem, root.itemAtIndex(itemIndex + 2));
|
||||
}
|
||||
// index 0 insertion = new message
|
||||
if (itemIndex === 0) {
|
||||
@ -88,57 +86,56 @@ JamiListView {
|
||||
// This needs to be done in a delayed fashion because the new message is inserted
|
||||
// at the top of the list and the list is not yet updated.
|
||||
Qt.callLater(() => {
|
||||
var fItem = root.itemAtIndex(1)
|
||||
if (fItem) {
|
||||
computeTimestampVisibility(item, 0, fItem, 1)
|
||||
computeSequencing(null, item, fItem)
|
||||
computeSequencing(item, fItem, root.itemAtIndex(2))
|
||||
}
|
||||
})
|
||||
var fItem = root.itemAtIndex(1);
|
||||
if (fItem) {
|
||||
computeTimestampVisibility(item, 0, fItem, 1);
|
||||
computeSequencing(null, item, fItem);
|
||||
computeSequencing(item, fItem, root.itemAtIndex(2));
|
||||
}
|
||||
});
|
||||
}
|
||||
// top element
|
||||
if(itemIndex === root.count - 1 && CurrentConversation.allMessagesLoaded) {
|
||||
item.showTime = true
|
||||
item.showDay = true
|
||||
if (itemIndex === root.count - 1 && CurrentConversation.allMessagesLoaded) {
|
||||
item.showTime = true;
|
||||
item.showDay = true;
|
||||
}
|
||||
}
|
||||
|
||||
function computeSequencing(pItem, item, nItem) {
|
||||
if (root === undefined || !item)
|
||||
return
|
||||
|
||||
return;
|
||||
function isFirst() {
|
||||
if (!nItem) return true
|
||||
if (!nItem)
|
||||
return true;
|
||||
else {
|
||||
if (item.showTime || item.isReply ) {
|
||||
return true
|
||||
if (item.showTime || item.isReply) {
|
||||
return true;
|
||||
} else if (nItem.author !== item.author) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
function isLast() {
|
||||
if (!pItem) return true
|
||||
if (!pItem)
|
||||
return true;
|
||||
else {
|
||||
if (pItem.showTime || pItem.isReply) {
|
||||
return true
|
||||
return true;
|
||||
} else if (pItem.author !== item.author) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLast() && isFirst())
|
||||
item.seq = MsgSeq.single
|
||||
item.seq = MsgSeq.single;
|
||||
if (!isLast() && isFirst())
|
||||
item.seq = MsgSeq.first
|
||||
item.seq = MsgSeq.first;
|
||||
if (isLast() && !isFirst())
|
||||
item.seq = MsgSeq.last
|
||||
item.seq = MsgSeq.last;
|
||||
if (!isLast() && !isFirst())
|
||||
item.seq = MsgSeq.middle
|
||||
item.seq = MsgSeq.middle;
|
||||
}
|
||||
|
||||
// fade-in mechanism
|
||||
@ -151,12 +148,16 @@ JamiListView {
|
||||
SequentialAnimation {
|
||||
id: fadeAnimation
|
||||
NumberAnimation {
|
||||
target: overlay; property: "opacity"
|
||||
to: 1; duration: 0
|
||||
target: overlay
|
||||
property: "opacity"
|
||||
to: 1
|
||||
duration: 0
|
||||
}
|
||||
NumberAnimation {
|
||||
target: overlay; property: "opacity"
|
||||
to: 0; duration: 240
|
||||
target: overlay
|
||||
property: "opacity"
|
||||
to: 0
|
||||
duration: 240
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -167,7 +168,7 @@ JamiListView {
|
||||
anchors.fill: parent
|
||||
|
||||
function instantiateToast(dest) {
|
||||
instantiate(JamiStrings.fileSaved.arg(dest), 1000, 400)
|
||||
instantiate(JamiStrings.fileSaved.arg(dest), 1000, 400);
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,8 +176,8 @@ JamiListView {
|
||||
target: CurrentConversation
|
||||
function onScrollTo(id) {
|
||||
// Get the filtered index from the interaction ID.
|
||||
var idx = MessagesAdapter.messageListModel.getDisplayIndex(id)
|
||||
positionViewAtIndex(idx, ListView.Visible)
|
||||
var idx = MessagesAdapter.messageListModel.getDisplayIndex(id);
|
||||
positionViewAtIndex(idx, ListView.Visible);
|
||||
}
|
||||
}
|
||||
|
||||
@ -203,8 +204,8 @@ JamiListView {
|
||||
roleValue: Interaction.Type.TEXT
|
||||
|
||||
TextMessageDelegate {
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index)
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,8 +214,8 @@ JamiListView {
|
||||
roleValue: Interaction.Type.CALL
|
||||
|
||||
CallMessageDelegate {
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index)
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -223,8 +224,8 @@ JamiListView {
|
||||
roleValue: Interaction.Type.CONTACT
|
||||
|
||||
ContactMessageDelegate {
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index)
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,8 +235,8 @@ JamiListView {
|
||||
|
||||
GeneratedMessageDelegate {
|
||||
font.bold: true
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index)
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -244,12 +245,11 @@ JamiListView {
|
||||
roleValue: Interaction.Type.DATA_TRANSFER
|
||||
|
||||
DataTransferMessageDelegate {
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index)
|
||||
Component.onCompleted: {
|
||||
computeChatview(this, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
onAtYBeginningChanged: loadMoreMsgsIfNeeded()
|
||||
@ -271,9 +271,8 @@ JamiListView {
|
||||
target: MessagesAdapter
|
||||
|
||||
function onNewInteraction() {
|
||||
if (root.getDistanceToBottom() < 80 &&
|
||||
!root.atYEnd) {
|
||||
Qt.callLater(root.positionViewAtBeginning)
|
||||
if (root.getDistanceToBottom() < 80 && !root.atYEnd) {
|
||||
Qt.callLater(root.positionViewAtBeginning);
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +283,7 @@ JamiListView {
|
||||
}
|
||||
|
||||
function onFileCopied(dest) {
|
||||
toastManager.instantiateToast(dest)
|
||||
toastManager.instantiateToast(dest);
|
||||
}
|
||||
}
|
||||
|
||||
@ -294,7 +293,7 @@ JamiListView {
|
||||
anchors.bottom: root.bottom
|
||||
anchors.bottomMargin: JamiTheme.chatViewScrollToBottomButtonBottomMargin
|
||||
anchors.horizontalCenter: root.horizontalCenter
|
||||
visible: 1 - verticalScrollBar.position >= verticalScrollBar.size * 2
|
||||
visible: 1 - verticalScrollBar.position >= verticalScrollBar.size * 2
|
||||
|
||||
onClicked: scrollToBottom()
|
||||
}
|
||||
@ -326,36 +325,31 @@ JamiListView {
|
||||
Connections {
|
||||
target: MessagesAdapter
|
||||
|
||||
function onCurrentConvComposingListChanged () {
|
||||
var typeIndicatorNameTextString = ""
|
||||
var nameList = MessagesAdapter.currentConvComposingList
|
||||
|
||||
function onCurrentConvComposingListChanged() {
|
||||
var typeIndicatorNameTextString = "";
|
||||
var nameList = MessagesAdapter.currentConvComposingList;
|
||||
if (nameList.length > 4) {
|
||||
typeIndicatorNameText.text = ""
|
||||
typeIndicatorEndingText.text = JamiStrings.typeIndicatorMax
|
||||
typeIndicatorNameText.calculateWidth()
|
||||
return
|
||||
typeIndicatorNameText.text = "";
|
||||
typeIndicatorEndingText.text = JamiStrings.typeIndicatorMax;
|
||||
typeIndicatorNameText.calculateWidth();
|
||||
return;
|
||||
}
|
||||
if (nameList.length === 1) {
|
||||
typeIndicatorNameText.text = nameList[0]
|
||||
typeIndicatorEndingText.text =
|
||||
JamiStrings.typeIndicatorSingle.replace("{}", "")
|
||||
typeIndicatorNameText.calculateWidth()
|
||||
return
|
||||
typeIndicatorNameText.text = nameList[0];
|
||||
typeIndicatorEndingText.text = JamiStrings.typeIndicatorSingle.replace("{}", "");
|
||||
typeIndicatorNameText.calculateWidth();
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < nameList.length; i++) {
|
||||
typeIndicatorNameTextString += nameList[i]
|
||||
|
||||
typeIndicatorNameTextString += nameList[i];
|
||||
if (i === nameList.length - 2)
|
||||
typeIndicatorNameTextString += JamiStrings.typeIndicatorAnd
|
||||
typeIndicatorNameTextString += JamiStrings.typeIndicatorAnd;
|
||||
else if (i !== nameList.length - 1)
|
||||
typeIndicatorNameTextString += ", "
|
||||
typeIndicatorNameTextString += ", ";
|
||||
}
|
||||
typeIndicatorNameText.text = typeIndicatorNameTextString
|
||||
typeIndicatorEndingText.text =
|
||||
JamiStrings.typeIndicatorPlural.replace("{}", "")
|
||||
typeIndicatorNameText.calculateWidth()
|
||||
typeIndicatorNameText.text = typeIndicatorNameTextString;
|
||||
typeIndicatorEndingText.text = JamiStrings.typeIndicatorPlural.replace("{}", "");
|
||||
typeIndicatorNameText.calculateWidth();
|
||||
}
|
||||
}
|
||||
|
||||
@ -364,17 +358,13 @@ JamiListView {
|
||||
|
||||
property int textWidth: 0
|
||||
|
||||
function calculateWidth () {
|
||||
function calculateWidth() {
|
||||
if (!text)
|
||||
return 0
|
||||
return 0;
|
||||
else {
|
||||
var textSize = JamiQmlUtils.getTextBoundingRect(font, text).width
|
||||
var typingContentWidth = typingDots.width + typingDots.anchors.leftMargin
|
||||
+ typeIndicatorNameText.anchors.leftMargin
|
||||
+ typeIndicatorEndingText.contentWidth
|
||||
typeIndicatorNameText.Layout.preferredWidth =
|
||||
Math.min(typeIndicatorContainer.width - 5 - typingContentWidth,
|
||||
textSize)
|
||||
var textSize = JamiQmlUtils.getTextBoundingRect(font, text).width;
|
||||
var typingContentWidth = typingDots.width + typingDots.anchors.leftMargin + typeIndicatorNameText.anchors.leftMargin + typeIndicatorEndingText.contentWidth;
|
||||
typeIndicatorNameText.Layout.preferredWidth = Math.min(typeIndicatorContainer.width - 5 - typingContentWidth, textSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -98,7 +98,6 @@ Page {
|
||||
underlineColor: CurrentConversation.color
|
||||
underlineColorHovered: CurrentConversation.color
|
||||
|
||||
|
||||
down: researchTabBar.currentIndex === 1
|
||||
labelText: JamiStrings.files
|
||||
Layout.fillWidth: true
|
||||
|
||||
@ -150,7 +150,7 @@ DualPaneView {
|
||||
Layout.preferredWidth: JamiTheme.preferredFieldWidth
|
||||
|
||||
staticText: ""
|
||||
placeholderText: JamiStrings.swarmName
|
||||
placeholderText: JamiStrings.groupName
|
||||
|
||||
textColor: {
|
||||
if (UtilsAdapter.luma(root.color)) {
|
||||
@ -174,7 +174,7 @@ DualPaneView {
|
||||
Layout.preferredWidth: JamiTheme.preferredFieldWidth
|
||||
|
||||
staticText: ""
|
||||
placeholderText: JamiStrings.addADescription
|
||||
placeholderText: JamiStrings.addDescription
|
||||
|
||||
textColor: {
|
||||
if (UtilsAdapter.luma(root.color)) {
|
||||
@ -205,7 +205,7 @@ DualPaneView {
|
||||
preferredWidth: textSize.width + 2 * JamiTheme.buttontextWizzardPadding
|
||||
|
||||
primary: true
|
||||
text: JamiStrings.createTheSwarm
|
||||
text: JamiStrings.newGroup
|
||||
|
||||
onClicked: createSwarmClicked(title.dynamicText, description.dynamicText, UtilsAdapter.tempCreationImage())
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: joinCallInAudio
|
||||
id: joinCallWithAudio
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Layout.rightMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
@ -68,7 +68,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: joinCallInVideo
|
||||
id: joinCallWithVideo
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
Layout.rightMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
@ -98,7 +98,7 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
from: 0
|
||||
duration: JamiTheme.shortFadeDuration
|
||||
|
||||
@ -95,7 +95,7 @@ Popup {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: JamiTheme.textColor
|
||||
|
||||
text: JamiStrings.choosePlugin
|
||||
text: JamiStrings.chooseExtension
|
||||
}
|
||||
|
||||
PushButton {
|
||||
@ -176,7 +176,7 @@ Popup {
|
||||
Layout.leftMargin: 5
|
||||
Layout.topMargin: 5
|
||||
|
||||
toolTipText: JamiStrings.goBackToPluginsList
|
||||
toolTipText: JamiStrings.goBackToExtensionsList
|
||||
|
||||
onClicked: {
|
||||
stack.pop(null, StackView.Immediate);
|
||||
@ -195,7 +195,7 @@ Popup {
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
color: JamiTheme.textColor
|
||||
text: JamiStrings.pluginPreferences
|
||||
text: JamiStrings.extensionPreferences
|
||||
}
|
||||
|
||||
PushButton {
|
||||
|
||||
@ -214,7 +214,7 @@ SidePanelBase {
|
||||
font.bold: true
|
||||
font.pointSize: JamiTheme.contactEventPointSize
|
||||
|
||||
text: JamiStrings.createSwarm
|
||||
text: JamiStrings.newGroup
|
||||
}
|
||||
|
||||
PushButton {
|
||||
@ -288,7 +288,7 @@ SidePanelBase {
|
||||
visible: !swarmMemberSearchList.visible && CurrentAccount.type !== Profile.Type.SIP
|
||||
|
||||
source: smartListLayout.visible ? JamiResources.create_swarm_svg : JamiResources.round_close_24dp_svg
|
||||
toolTipText: smartListLayout.visible ? JamiStrings.startSwarm : JamiStrings.cancel
|
||||
toolTipText: smartListLayout.visible ? JamiStrings.newGroup : JamiStrings.cancel
|
||||
|
||||
onClicked: toggleCreateSwarmView()
|
||||
}
|
||||
|
||||
@ -38,9 +38,9 @@ ItemDelegate {
|
||||
|
||||
highlighted: ListView.isCurrentItem
|
||||
property bool interactive: true
|
||||
property string lastInteractionDate: LastInteractionTimeStamp === undefined ? "" : LastInteractionTimeStamp
|
||||
|
||||
property string lastInteractionFormattedDate: MessagesAdapter.getBestFormattedDate(lastInteractionDate)
|
||||
property int lastInteractionTimeStamp: LastInteractionTimeStamp
|
||||
property string lastInteractionFormattedDate: MessagesAdapter.getBestFormattedDate(lastInteractionTimeStamp)
|
||||
|
||||
property bool showSharePositionIndicator: PositionManager.isPositionSharedToConv(accountId, UID)
|
||||
property bool showSharedPositionIndicator: PositionManager.isConvSharingPosition(accountId, UID)
|
||||
@ -58,7 +58,7 @@ ItemDelegate {
|
||||
Connections {
|
||||
target: MessagesAdapter
|
||||
function onTimestampUpdated() {
|
||||
lastInteractionFormattedDate = MessagesAdapter.getBestFormattedDate(lastInteractionDate);
|
||||
lastInteractionFormattedDate = MessagesAdapter.getBestFormattedDate(lastInteractionTimeStamp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +130,7 @@ ItemDelegate {
|
||||
color: JamiTheme.textColor
|
||||
}
|
||||
RowLayout {
|
||||
visible: ContactType !== Profile.Type.TEMPORARY && !IsBanned && lastInteractionFormattedDate !== undefined && interactive
|
||||
visible: ContactType !== Profile.Type.TEMPORARY && !IsBanned && lastInteractionTimeStamp > 0 && interactive
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 20
|
||||
Layout.alignment: Qt.AlignTop
|
||||
@ -138,7 +138,7 @@ ItemDelegate {
|
||||
// last Interaction date
|
||||
Text {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: lastInteractionFormattedDate === undefined ? "" : lastInteractionFormattedDate
|
||||
text: lastInteractionFormattedDate
|
||||
textFormat: TextEdit.PlainText
|
||||
font.pointSize: JamiTheme.smallFontSize
|
||||
font.weight: UnreadMessagesCount ? Font.DemiBold : Font.Normal
|
||||
@ -164,7 +164,7 @@ ItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
Layout.minimumHeight: 20
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: JamiStrings.banned
|
||||
text: JamiStrings.blocked
|
||||
textFormat: TextEdit.PlainText
|
||||
visible: IsBanned
|
||||
font.pointSize: JamiTheme.mediumFontSize
|
||||
|
||||
@ -115,7 +115,7 @@ Rectangle {
|
||||
titleLine.editMode = activeFocus;
|
||||
}
|
||||
|
||||
infoTipLineText: CurrentConversation.isCoreDialog ? JamiStrings.contactName : JamiStrings.swarmName
|
||||
infoTipLineText: CurrentConversation.isCoreDialog ? JamiStrings.contactName : JamiStrings.groupName
|
||||
}
|
||||
|
||||
ModalTextEdit {
|
||||
@ -139,7 +139,7 @@ Rectangle {
|
||||
Layout.rightMargin: 2 * JamiTheme.settingsMarginSize
|
||||
|
||||
staticText: CurrentConversation.description
|
||||
placeholderText: JamiStrings.addADescription
|
||||
placeholderText: JamiStrings.addDescription
|
||||
elidedText: descriptionLineButtonTextSize.elidedText
|
||||
|
||||
textColor: root.textColor
|
||||
@ -156,7 +156,7 @@ Rectangle {
|
||||
descriptionLineButton.editMode = activeFocus;
|
||||
}
|
||||
|
||||
infoTipLineText: JamiStrings.addADescription
|
||||
infoTipLineText: JamiStrings.addDescription
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -663,7 +663,7 @@ Rectangle {
|
||||
if (MemberRole === Member.Role.INVITED)
|
||||
return JamiStrings.invited;
|
||||
if (MemberRole === Member.Role.BANNED)
|
||||
return JamiStrings.banned;
|
||||
return JamiStrings.blocked;
|
||||
return "";
|
||||
}
|
||||
maxWidth: JamiTheme.preferredFieldWidth
|
||||
|
||||
@ -30,7 +30,7 @@ ContextMenuAutoLoader {
|
||||
|
||||
property list<GeneralMenuItem> menuItems: [
|
||||
GeneralMenuItem {
|
||||
id: startVideoCallItem
|
||||
id: startVideoCall
|
||||
itemName: JamiStrings.startVideoCall
|
||||
canTrigger: ConversationsAdapter.dialogId(participantUri) !== ""
|
||||
iconSource: JamiResources.videocam_24dp_svg
|
||||
|
||||
@ -46,7 +46,6 @@ function finishCreation() {
|
||||
}
|
||||
|
||||
function showKeyboardShortcutTableWindow() {
|
||||
keyboardShortcutTableWindowObject.show()
|
||||
var centerX = mainWindow.x + mainWindow.width / 2
|
||||
var centerY = mainWindow.y + mainWindow.height / 2
|
||||
|
||||
@ -54,6 +53,11 @@ function showKeyboardShortcutTableWindow() {
|
||||
keyboardShortcutTableWindowObject.height = 0.75 * appWindow.height
|
||||
keyboardShortcutTableWindowObject.x = centerX - keyboardShortcutTableWindowObject.width / 2
|
||||
keyboardShortcutTableWindowObject.y = centerY - keyboardShortcutTableWindowObject.height / 2
|
||||
|
||||
keyboardShortcutTableWindowObject.visible = true
|
||||
keyboardShortcutTableWindowObject.show()
|
||||
keyboardShortcutTableWindowObject.raise()
|
||||
keyboardShortcutTableWindowObject.requestActivate()
|
||||
}
|
||||
|
||||
// Destroy and reset selectScreenWindowObject when window is closed.
|
||||
|
||||
@ -165,6 +165,16 @@ MessagesAdapter::sendMessage(const QString& message)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessagesAdapter::sendMessageToUid(const QString& message, const QString& convUid)
|
||||
{
|
||||
try {
|
||||
lrcInstance_->getCurrentConversationModel()->sendMessage(convUid, message, replyToId_);
|
||||
} catch (...) {
|
||||
qDebug() << "Exception during sendMessage:" << message;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessagesAdapter::editMessage(const QString& convId, const QString& newBody, const QString& messageId)
|
||||
{
|
||||
@ -221,6 +231,21 @@ MessagesAdapter::sendFile(const QString& message)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessagesAdapter::sendFileToUid(const QString& message, const QString& convUid)
|
||||
{
|
||||
QFileInfo fi(message);
|
||||
QString fileName = fi.fileName();
|
||||
try {
|
||||
lrcInstance_->getCurrentConversationModel()->sendFile(convUid,
|
||||
message,
|
||||
fileName,
|
||||
replyToId_);
|
||||
} catch (...) {
|
||||
qDebug() << "Exception during sendFile";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessagesAdapter::joinCall(const QString& uri,
|
||||
const QString& deviceId,
|
||||
@ -312,8 +337,7 @@ MessagesAdapter::onPaste()
|
||||
QString path = QDir::temp().filePath(fileName);
|
||||
|
||||
if (!pixmap.save(path, "PNG")) {
|
||||
qDebug().noquote() << "Errors during QPixmap save"
|
||||
<< "\n";
|
||||
qDebug().noquote() << "Errors during QPixmap save" << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -335,40 +359,6 @@ MessagesAdapter::onPaste()
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
MessagesAdapter::getStatusString(int status)
|
||||
{
|
||||
switch (static_cast<interaction::Status>(status)) {
|
||||
case interaction::Status::SENDING:
|
||||
return QObject::tr("Sending");
|
||||
case interaction::Status::FAILURE:
|
||||
return QObject::tr("Failure");
|
||||
case interaction::Status::SUCCESS:
|
||||
return QObject::tr("Sent");
|
||||
case interaction::Status::TRANSFER_CREATED:
|
||||
return QObject::tr("Connecting");
|
||||
case interaction::Status::TRANSFER_ACCEPTED:
|
||||
return QObject::tr("Accept");
|
||||
case interaction::Status::TRANSFER_CANCELED:
|
||||
return QObject::tr("Canceled");
|
||||
case interaction::Status::TRANSFER_ERROR:
|
||||
case interaction::Status::TRANSFER_UNJOINABLE_PEER:
|
||||
return QObject::tr("Unable to make contact");
|
||||
case interaction::Status::TRANSFER_ONGOING:
|
||||
return QObject::tr("Ongoing");
|
||||
case interaction::Status::TRANSFER_AWAITING_PEER:
|
||||
return QObject::tr("Waiting for contact");
|
||||
case interaction::Status::TRANSFER_AWAITING_HOST:
|
||||
return QObject::tr("Incoming transfer");
|
||||
case interaction::Status::TRANSFER_TIMEOUT_EXPIRED:
|
||||
return QObject::tr("Timed out waiting for contact");
|
||||
case interaction::Status::TRANSFER_FINISHED:
|
||||
return QObject::tr("Finished");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
QVariantMap
|
||||
MessagesAdapter::getTransferStats(const QString& msgId, int status)
|
||||
{
|
||||
|
||||
@ -126,6 +126,7 @@ public:
|
||||
Q_INVOKABLE void unbanContact(int index);
|
||||
Q_INVOKABLE void unbanConversation(const QString& convUid);
|
||||
Q_INVOKABLE void sendMessage(const QString& message);
|
||||
Q_INVOKABLE void sendMessageToUid(const QString& message, const QString& convUid);
|
||||
Q_INVOKABLE void editMessage(const QString& convId,
|
||||
const QString& newBody,
|
||||
const QString& messageId = "");
|
||||
@ -136,6 +137,7 @@ public:
|
||||
const QString& emoji,
|
||||
const QString& messageId);
|
||||
Q_INVOKABLE void sendFile(const QString& message);
|
||||
Q_INVOKABLE void sendFileToUid(const QString& message, const QString& convUid);
|
||||
Q_INVOKABLE void acceptFile(const QString& arg);
|
||||
Q_INVOKABLE void cancelFile(const QString& arg);
|
||||
Q_INVOKABLE void openUrl(const QString& url);
|
||||
@ -159,7 +161,6 @@ public:
|
||||
const QColor& linkColor = QColor(0x06, 0x45, 0xad),
|
||||
const QColor& backgroundColor = QColor(0x0, 0x0, 0x0));
|
||||
Q_INVOKABLE void onPaste();
|
||||
Q_INVOKABLE QString getStatusString(int status);
|
||||
Q_INVOKABLE QVariantMap getTransferStats(const QString& messageId, int);
|
||||
Q_INVOKABLE QVariant dataForInteraction(const QString& interactionId,
|
||||
int role = Qt::DisplayRole) const;
|
||||
|
||||
@ -29,25 +29,26 @@ Item {
|
||||
property string accept: qsTr("Accept")
|
||||
property string acceptAudio: qsTr("Accept in audio")
|
||||
property string acceptVideo: qsTr("Accept in video")
|
||||
property string refuse: qsTr("Refuse")
|
||||
property string refuse: qsTr("Decline")
|
||||
property string endCall: qsTr("End call")
|
||||
property string incomingAudioCallFrom: qsTr("Incoming audio call from {}")
|
||||
property string incomingVideoCallFrom: qsTr("Incoming video call from {}")
|
||||
property string startSwarm: qsTr("Start swarm")
|
||||
property string createSwarm: qsTr("Create swarm")
|
||||
property string newGroup: qsTr("Create new group")
|
||||
property string invitations: qsTr("Invitations")
|
||||
property string description: qsTr("Jami is a universal communication platform, with privacy as its foundation, that relies on a free distributed network for everyone.")
|
||||
property string updateToSwarm: qsTr("Migrating to the Swarm technology will enable synchronizing this conversation across multiple devices and improve reliability. The legacy conversation history will be cleared in the process.")
|
||||
property string migrateConversation: qsTr("Migrate conversation")
|
||||
|
||||
// DaemonReconnectWindow
|
||||
property string reconnectWarn: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
|
||||
property string reconnectTry: qsTr("Trying to reconnect to the Jami daemon (jamid)…")
|
||||
property string reconnectWarn: qsTr("An error occurred while attempting to reconnect to the Jami daemon (jamid).\nJami will now quit.")
|
||||
property string reconnectAttempt: qsTr("Attempting to reconnect to the Jami daemon (jamid)…")
|
||||
|
||||
// AboutPopUp
|
||||
property string version: qsTr("Version") + (AppVersionManager.isCurrentVersionBeta() ? " (Beta)" : "")
|
||||
property string buildID: qsTr("Build ID")
|
||||
property string version: qsTr("Version")
|
||||
|
||||
property string declarationYear: "© 2015-2024"
|
||||
property string slogan: "Eleutheria"
|
||||
property string slogan: "Astarte"
|
||||
property string declaration: qsTr('Jami, a GNU package, is software for universal and distributed peer-to-peer communication that respects the freedom and privacy of its users. Visit <a href="https://jami.net" style="color: ' + JamiTheme.buttonTintedBlue + '">jami.net</a>' + ' to learn more.')
|
||||
property string noWarranty: qsTr('This program comes with absolutely no warranty. See the <a href="https://www.gnu.org/licenses/gpl-3.0.html" style="color: ' + JamiTheme.buttonTintedBlue + '">GNU General Public License</a>, version 3 or later for details.')
|
||||
property string contribute: qsTr('Contribute')
|
||||
@ -73,7 +74,7 @@ Item {
|
||||
property string authenticate: qsTr("Authenticate")
|
||||
property string deleteAccount: qsTr("Delete account")
|
||||
property string inProgress: qsTr("In progress…")
|
||||
property string authenticationFailed: qsTr("Authentication failed")
|
||||
property string authenticationFailed: qsTr("An error occurred while authenticating account.")
|
||||
property string password: qsTr("Password")
|
||||
property string username: qsTr("Username")
|
||||
property string alias: qsTr("Alias")
|
||||
@ -85,8 +86,8 @@ Item {
|
||||
property string enableCustomRingtone: qsTr("Enable custom ringtone")
|
||||
property string selectCustomRingtone: qsTr("Select custom ringtone")
|
||||
property string selectNewRingtone: qsTr("Select a new ringtone")
|
||||
property string certificateFile: qsTr("Certificate File (*.crt)")
|
||||
property string audioFile: qsTr("Audio File (*.wav *.ogg *.opus *.mp3 *.aiff *.wma)")
|
||||
property string certificateFile: qsTr("Certificate file (*.crt)")
|
||||
property string audioFile: qsTr("Audio file (*.wav *.ogg *.opus *.mp3 *.aiff *.wma)")
|
||||
property string pushToTalk: qsTr("Push-to-talk")
|
||||
property string enablePTT: qsTr("Enable push-to-talk")
|
||||
property string keyboardShortcut: qsTr("Keyboard shortcut")
|
||||
@ -117,11 +118,11 @@ Item {
|
||||
property string verifyCertificatesClient: qsTr("Verify server TLS certificates")
|
||||
property string tlsRequireConnections: qsTr("Require certificate for incoming TLS connections")
|
||||
property string disableSecureDlgCheck: qsTr("Disable secure dialog check for incoming TLS data")
|
||||
property string selectPrivateKey: qsTr("Select a private key")
|
||||
property string selectUserCert: qsTr("Select a user certificate")
|
||||
property string selectCACert: qsTr("Select a CA certificate")
|
||||
property string selectPrivateKey: qsTr("Select private key")
|
||||
property string selectUserCert: qsTr("Select user certificate")
|
||||
property string selectCACert: qsTr("Select CA certificate")
|
||||
property string selectCACertDefault: qsTr("Select")
|
||||
property string keyFile: qsTr("Key File (*.key)")
|
||||
property string keyFile: qsTr("Key file (*.key)")
|
||||
|
||||
// AdvancedConnectivitySettings
|
||||
property string connectivity: qsTr("Connectivity")
|
||||
@ -133,7 +134,7 @@ Item {
|
||||
property string turnAdress: qsTr("TURN address")
|
||||
property string turnUsername: qsTr("TURN username")
|
||||
property string turnPassword: qsTr("TURN password")
|
||||
property string turnRealm: qsTr("TURN Realm")
|
||||
property string turnRealm: qsTr("TURN realm")
|
||||
property string useSTUN: qsTr("Use STUN")
|
||||
property string stunAdress: qsTr("STUN address")
|
||||
|
||||
@ -174,14 +175,14 @@ Item {
|
||||
property string back: qsTr("Back")
|
||||
property string accountSettingsMenuTitle: qsTr("Account")
|
||||
property string generalSettingsTitle: qsTr("General")
|
||||
property string pluginSettingsTitle: qsTr("Extensions")
|
||||
property string extensionSettingsTitle: qsTr("Extensions")
|
||||
property string enableAccountSettingsTitle: qsTr("Enable account")
|
||||
property string manageAccountSettingsTitle: qsTr("Manage account")
|
||||
property string linkedDevicesSettingsTitle: qsTr("Linked devices")
|
||||
property string callSettingsTitle: qsTr("Call settings")
|
||||
property string chatSettingsTitle: qsTr("Chat")
|
||||
property string advancedSettingsTitle: qsTr("Advanced settings")
|
||||
property string audioVideoSettingsTitle: qsTr("Audio and Video")
|
||||
property string mediaSettingsTitle: qsTr("Media")
|
||||
|
||||
// AudioSettings
|
||||
property string audio: qsTr("Audio")
|
||||
@ -206,7 +207,7 @@ Item {
|
||||
property string mirrorLocalVideo: qsTr("Mirror local video")
|
||||
property string screenSharing: qsTr("Screen sharing")
|
||||
property string selectScreenSharingFPS: qsTr("Select screen sharing frame rate (frames per second)")
|
||||
property string noVideo: qsTr("no video")
|
||||
property string noCamera: qsTr("No camera available")
|
||||
|
||||
// BackupKeyPage
|
||||
property string whyBackupAccount: qsTr("Why should I back-up this account?")
|
||||
@ -218,8 +219,7 @@ Item {
|
||||
property string jamiArchiveFiles: qsTr("Jami archive files (*.gz)")
|
||||
property string allFiles: qsTr("All files (*)")
|
||||
|
||||
// BannedItemDelegate
|
||||
property string reinstateContact: qsTr("Reinstate as contact")
|
||||
// ContactItemDelegate
|
||||
property string name: qsTr("name")
|
||||
property string identifier: qsTr("Identifier")
|
||||
|
||||
@ -230,10 +230,10 @@ Item {
|
||||
property string unmute: qsTr("Unmute")
|
||||
property string pauseCall: qsTr("Pause call")
|
||||
property string resumeCall: qsTr("Resume call")
|
||||
property string muteCamera: qsTr("Mute camera")
|
||||
property string unmuteCamera: qsTr("Unmute camera")
|
||||
property string addParticipant: qsTr("Add participant")
|
||||
property string addParticipants: qsTr("Add participants")
|
||||
property string stopCamera: qsTr("Stop camera")
|
||||
property string startCamera: qsTr("Start camera")
|
||||
property string inviteMember: qsTr("Invite member")
|
||||
property string inviteMembers: qsTr("Invite members")
|
||||
property string details: qsTr("Details")
|
||||
property string chat: qsTr("Chat")
|
||||
property string moreOptions: qsTr("More options")
|
||||
@ -259,20 +259,20 @@ Item {
|
||||
property string paste: qsTr("Paste")
|
||||
|
||||
// ConversationContextMenu
|
||||
property string startVideoCall: qsTr("Start video call")
|
||||
property string startAudioCall: qsTr("Start audio call")
|
||||
property string startVideoCall: qsTr("Start video call")
|
||||
property string clearConversation: qsTr("Clear conversation")
|
||||
property string confirmAction: qsTr("Confirm action")
|
||||
property string removeConversation: qsTr("Remove conversation")
|
||||
property string confirmRmConversation: qsTr("Would you really like to remove this conversation?")
|
||||
property string confirmBlockConversation: qsTr("Would you really like to block this conversation?")
|
||||
property string removeConversation: qsTr("Leave conversation")
|
||||
property string confirmRmConversation: qsTr("Do you really want to leave this conversation?")
|
||||
property string confirmBlockConversation: qsTr("Do you really want to block this conversation?")
|
||||
property string removeContact: qsTr("Remove contact")
|
||||
property string blockContact: qsTr("Block contact")
|
||||
property string convDetails: qsTr("Conversation details")
|
||||
property string contactDetails: qsTr("Contact details")
|
||||
|
||||
// CallViewContextMenu
|
||||
property string sipInputPanel: qsTr("Sip input panel")
|
||||
property string sipInputPanel: qsTr("DTMF input panel")
|
||||
property string transferCall: qsTr("Transfer call")
|
||||
property string stopRec: qsTr("Stop recording")
|
||||
property string startRec: qsTr("Start recording")
|
||||
@ -283,7 +283,7 @@ Item {
|
||||
property string shareScreenArea: qsTr("Share screen area")
|
||||
property string shareFile: qsTr("Share file")
|
||||
property string selectShareMethod: qsTr("Select sharing method")
|
||||
property string viewPlugin: qsTr("View plugin")
|
||||
property string viewExtension: qsTr("View extension")
|
||||
property string advancedInformation: qsTr("Advanced information")
|
||||
property string noVideoDevice: qsTr("No video device")
|
||||
property string notAvailable: qsTr("Unavailable")
|
||||
@ -294,7 +294,7 @@ Item {
|
||||
property string screenshotTaken: qsTr("Screenshot saved to %1")
|
||||
property string fileSaved: qsTr("File saved to %1")
|
||||
|
||||
//advanced information
|
||||
// Advanced information
|
||||
property string renderersInformation: qsTr("Renderers information")
|
||||
property string callInformation: qsTr("Call information")
|
||||
property string peerNumber: qsTr("Peer number")
|
||||
@ -310,8 +310,8 @@ Item {
|
||||
// Share location/position
|
||||
property string shareLocation: qsTr("Share location")
|
||||
property string stopSharingLocation: qsTr("Stop sharing")
|
||||
property string locationServicesError: qsTr("Your precise location could not be determined.\nIn Device Settings, please turn on \"Location Services\".\nOther participants' location can still be received.")
|
||||
property string locationServicesClosedError: qsTr("Your precise location could not be determined. Please check your Internet connection.")
|
||||
property string locationServicesError: qsTr("An error occurred while sharing device location.\nEnable “Location Services” in device settings in order to use this feature.\nThe location of other members can still be received.")
|
||||
property string locationServicesClosedError: qsTr("An error occurred while sharing device location. Please check your Internet connection and try again.")
|
||||
property string stopAllSharings: qsTr("Turn off location sharing")
|
||||
property string shortStopAllSharings: qsTr("Turn off sharing")
|
||||
property string stopConvSharing: qsTr("Stop location sharing in this conversation (%1)")
|
||||
@ -338,17 +338,16 @@ Item {
|
||||
|
||||
// Chatview header
|
||||
property string hideChat: qsTr("Hide chat")
|
||||
property string placeAudioCall: qsTr("Place audio call")
|
||||
property string placeVideoCall: qsTr("Place video call")
|
||||
property string showPlugins: qsTr("Show available plugins")
|
||||
property string showExtensions: qsTr("Show available extensions")
|
||||
property string addToConversations: qsTr("Add to conversations")
|
||||
property string backendError: qsTr("This is the error from the backend: %0")
|
||||
property string backendError: qsTr("A backend system error occurred: %0")
|
||||
property string disabledAccount: qsTr("The account is disabled")
|
||||
property string noNetworkConnectivity: qsTr("No network connectivity")
|
||||
property string deletedMessage: qsTr("deleted a message")
|
||||
property string backCall: qsTr("Back to Call")
|
||||
property string deletedMedia: qsTr("deleted a media")
|
||||
property string returnToCall: qsTr("Return to call")
|
||||
|
||||
//MessagesResearch
|
||||
// MessagesResearch
|
||||
property string jumpTo: qsTr("Jump to")
|
||||
property string messages: qsTr("Messages")
|
||||
property string files: qsTr("Files")
|
||||
@ -379,7 +378,7 @@ Item {
|
||||
property string invalidUsername: qsTr("Invalid username")
|
||||
property string nameAlreadyTaken: qsTr("Name already taken")
|
||||
property string usernameAlreadyTaken: qsTr("Username already taken")
|
||||
property string joinJamiNoPassword: qsTr("Are you sure you would like to join Jami without a username?\nIf yes, only a randomly generated 40-character identifier will be assigned to this account.")
|
||||
property string joinJamiNoPassword: qsTr("Do you really want to join Jami without a username?\nIf yes, only a randomly generated 40-character identifier will be assigned to this account.")
|
||||
property string usernameToolTip: qsTr("- 32 characters maximum\n- Alphabetical characters (A to Z and a to z)\n- Numeric characters (0 to 9)\n- Special characters allowed: dash (-)")
|
||||
|
||||
// Good to know
|
||||
@ -395,12 +394,12 @@ Item {
|
||||
property string sipAccount: qsTr("SIP account")
|
||||
property string proxy: qsTr("Proxy")
|
||||
property string server: qsTr("Server")
|
||||
property string configureExistingSIP: qsTr("Configure an existing SIP account")
|
||||
property string configureExistingSIP: qsTr("Configure existing SIP account")
|
||||
property string personalizeAccount: qsTr("Personalize account")
|
||||
property string addSip: qsTr("Add SIP account")
|
||||
property string tls: qsTr("TLS")
|
||||
property string udp: qsTr("UDP")
|
||||
property string displayName: qsTr("Display Name")
|
||||
property string displayName: qsTr("Display name")
|
||||
|
||||
// accountSettingsPages
|
||||
property string customizeAccountDescription: qsTr("Your profile is only shared with your contacts.\nYour picture and your nickname can be changed at all time in the settings of your account.")
|
||||
@ -415,12 +414,12 @@ Item {
|
||||
property string linkedOtherDevices: qsTr("Other linked devices")
|
||||
|
||||
// CurrentAccountSettings && AdvancedSettings
|
||||
property string backupSuccessful: qsTr("Backup successful")
|
||||
property string backupFailed: qsTr("Backup failed")
|
||||
property string changePasswordSuccess: qsTr("Password changed successfully")
|
||||
property string changePasswordFailed: qsTr("Password change failed")
|
||||
property string setPasswordSuccess: qsTr("Password set successfully")
|
||||
property string setPasswordFailed: qsTr("Password set failed")
|
||||
property string backupSuccessful: qsTr("Backup completed successfully.")
|
||||
property string backupFailed: qsTr("An error occurred while backing up account.")
|
||||
property string changePasswordSuccess: qsTr("Password changed successfully.")
|
||||
property string changePasswordFailed: qsTr("An error occurred while changing account password.")
|
||||
property string setPasswordSuccess: qsTr("Password set successfully.")
|
||||
property string setPasswordFailed: qsTr("An error occurred while setting account password.")
|
||||
property string changePassword: qsTr("Change password")
|
||||
property string setPassword: qsTr("Encrypt account")
|
||||
property string setAPassword: qsTr("Set a password")
|
||||
@ -431,8 +430,8 @@ Item {
|
||||
property string advancedAccountSettings: qsTr("Advanced account settings")
|
||||
property string encryptAccount: qsTr("Encrypt account with password")
|
||||
property string customizeProfile: qsTr("Customize profile")
|
||||
property string customizeProfileDescription: qsTr("This profile is only shared with this account's contacts.\nThe profile can be changed at all times from the account's settings.")
|
||||
property string encryptTitle: qsTr("Encrypt account with a password")
|
||||
property string customizeProfileDescription: qsTr("This profile is only shared with account contacts.\nThe profile can be changed in account settings.")
|
||||
property string encryptTitle: qsTr("Encrypt account with password")
|
||||
property string encryptDescription: qsTr("A Jami account is created and stored locally only on this device, as an archive containing your account keys. Access to this archive can optionally be protected by a password.")
|
||||
property string encryptWarning: qsTr("Please note that if you lose your password, it CANNOT be recovered!")
|
||||
property string enterNickname: qsTr("Enter a nickname, surname…")
|
||||
@ -450,17 +449,18 @@ Item {
|
||||
// LinkedDevices
|
||||
property string tipLinkNewDevice: qsTr("Link a new device to this account")
|
||||
property string linkDevice: qsTr("Exporting account…")
|
||||
property string removeDevice: qsTr("Remove Device")
|
||||
property string sureToRemoveDevice: qsTr("Are you sure you wish to remove this device?")
|
||||
property string yourPinIs: qsTr("Your PIN is:")
|
||||
property string linkDeviceNetWorkError: qsTr("Error connecting to the network.\nPlease try again later.")
|
||||
property string removeDevice: qsTr("Remove device")
|
||||
property string confirmRemoveDevice: qsTr("Do you really want to unlink selected device? To continue, enter account password and click Unlink.")
|
||||
property string yourPinIs: qsTr("Account PIN code is:")
|
||||
property string linkDeviceNetWorkError: qsTr("A network error occurred while linking device.\nPlease try again later.")
|
||||
|
||||
// BannedContacts
|
||||
property string banned: qsTr("Banned")
|
||||
property string bannedContacts: qsTr("Banned contacts")
|
||||
property string reinstateContact: qsTr("Reinstate as contact")
|
||||
property string blocked: qsTr("Blocked")
|
||||
property string blockedContacts: qsTr("Blocked contacts")
|
||||
|
||||
// DeleteAccountDialog
|
||||
property string confirmDeleteQuestion: qsTr("Would you really like to delete this account?")
|
||||
property string confirmDeleteAccount: qsTr("Do you really want to delete this account? To continue, click Delete.")
|
||||
property string deleteAccountInfos: qsTr("If your account has not been backed up or added to another device, your account and registered username will be IRREVOCABLY LOST.")
|
||||
|
||||
// DeviceItemDelegate
|
||||
@ -498,14 +498,14 @@ Item {
|
||||
// File transfer settings
|
||||
property string fileTransfer: qsTr("File transfer")
|
||||
property string autoAcceptFiles: qsTr("Automatically accept incoming files")
|
||||
property string acceptTransferBelow: qsTr("Accept transfer limit (in Mb)")
|
||||
property string acceptTransferTooltip: qsTr("in MB, 0 = unlimited")
|
||||
property string acceptTransferBelow: qsTr("Accept transfer limit (Mb)")
|
||||
property string acceptTransferTooltip: qsTr("MB, 0 = unlimited")
|
||||
|
||||
// JamiUserIdentity settings
|
||||
property string register: qsTr("Register")
|
||||
property string incorrectPassword: qsTr("Incorrect password")
|
||||
property string networkError: qsTr("Network error")
|
||||
property string somethingWentWrong: qsTr("Something went wrong")
|
||||
property string incorrectPassword: qsTr("Incorrect password.")
|
||||
property string networkError: qsTr("A network error occurred.")
|
||||
property string somethingWentWrong: qsTr("An unexpected error occurred.")
|
||||
|
||||
// Context Menu
|
||||
property string saveFile: qsTr("Save file")
|
||||
@ -518,26 +518,26 @@ Item {
|
||||
property string enableAutoUpdates: qsTr("Enable/Disable automatic updates")
|
||||
property string updatesTitle: qsTr("Updates")
|
||||
property string updateDialogTitle: qsTr("Update")
|
||||
property string updateFound: qsTr("A new version of Jami was found\nWould you like to update now?")
|
||||
property string updateFound: qsTr("A new version of Jami was found.\nDo you want to update Jami now?\nTo continue, click Update.")
|
||||
property string updateNotFound: qsTr("No new version of Jami was found")
|
||||
property string updateCheckError: qsTr("An error occured when checking for a new version")
|
||||
property string updateNetworkError: qsTr("Network error")
|
||||
property string updateSSLError: qsTr("SSL error")
|
||||
property string updateDownloadCanceled: qsTr("Installer download canceled")
|
||||
property string updateCheckError: qsTr("An error occurred while checking for a new version.")
|
||||
property string updateNetworkError: qsTr("A network error occurred.")
|
||||
property string updateSSLError: qsTr("An SSL error occurred.")
|
||||
property string updateDownloadCanceled: qsTr("Installer download was canceled by user.")
|
||||
property string updateDownloading: "Downloading"
|
||||
property string confirmBeta: qsTr("This will uninstall your current Release version and you can always download the latest Release version on our website")
|
||||
property string confirmBeta: qsTr("This will replace the Release version with the Beta version on this device. The latest Release version can always be downloaded from the Jami website.")
|
||||
property string networkDisconnected: qsTr("Network disconnected")
|
||||
property string accessError: qsTr("Content access error")
|
||||
property string contentNotFoundError: qsTr("Content not found")
|
||||
property string genericError: qsTr("Something went wrong")
|
||||
property string accessError: qsTr("An error occurred while accessing contents.")
|
||||
property string contentNotFoundError: qsTr("Content not found.")
|
||||
property string genericError: qsTr("An unexpected error occurred.")
|
||||
|
||||
//Troubleshoot Settings
|
||||
// Troubleshoot Settings
|
||||
property string troubleshootTitle: qsTr("Troubleshoot")
|
||||
property string troubleshootButton: qsTr("Open logs")
|
||||
property string troubleshootText: qsTr("Get logs")
|
||||
|
||||
property string experimentalCallSwarm: qsTr("(Experimental) Enable call support for swarm")
|
||||
property string experimentalCallSwarmTooltip: qsTr("This feature will enable call buttons in swarms with multiple participants.")
|
||||
property string experimentalCallSwarm: qsTr("(Experimental) Enable call support for groups")
|
||||
property string experimentalCallSwarmTooltip: qsTr("This feature will enable the audio and video call buttons in group conversations.")
|
||||
|
||||
// Recording Settings
|
||||
property string quality: qsTr("Quality")
|
||||
@ -546,9 +546,9 @@ Item {
|
||||
property string callRecording: qsTr("Call recording")
|
||||
property string alwaysRecordCalls: qsTr("Always record calls")
|
||||
|
||||
// KeyboardShortCutTable
|
||||
property string keyboardShortcutTableWindowTitle: qsTr("Keyboard Shortcut Table")
|
||||
property string keyboardShortcuts: qsTr("Keyboard Shortcuts")
|
||||
// Keyboard shortcuts
|
||||
property string keyboardShortcutTableWindowTitle: qsTr("Keyboard shortcuts")
|
||||
property string keyboardShortcuts: qsTr("Keyboard shortcuts")
|
||||
property string conversationKeyboardShortcuts: qsTr("Conversation")
|
||||
property string callKeyboardShortcuts: qsTr("Call")
|
||||
property string settings: qsTr("Settings")
|
||||
@ -557,11 +557,11 @@ Item {
|
||||
// View Logs
|
||||
property string logsViewTitle: qsTr("Debug")
|
||||
property string logsViewCopy: qsTr("Copy")
|
||||
property string logsViewReport: qsTr("Report Bug")
|
||||
property string logsViewReport: qsTr("Submit issue")
|
||||
property string logsViewClear: qsTr("Clear")
|
||||
property string cancel: qsTr("Cancel")
|
||||
property string logsViewCopied: qsTr("Copied to clipboard!")
|
||||
property string logsViewDisplay: qsTr("Receive Logs")
|
||||
property string logsViewDisplay: qsTr("View logs")
|
||||
|
||||
// ImportFromBackupPage
|
||||
property string archive: qsTr("Archive")
|
||||
@ -577,29 +577,29 @@ Item {
|
||||
// ImportFromDevicePage
|
||||
property string importButton: qsTr("Import")
|
||||
property string pin: qsTr("Enter the PIN code")
|
||||
property string importFromDeviceDescription: qsTr("A PIN is required to use an existing Jami account on this device.")
|
||||
property string importStep1: qsTr("Step 01")
|
||||
property string importStep2: qsTr("Step 02")
|
||||
property string importStep3: qsTr("Step 03")
|
||||
property string importStep4: qsTr("Step 04")
|
||||
property string importStep1Desc: qsTr("Go to the account management settings of a previous device")
|
||||
property string importStep2Desc: qsTr("Choose the account to link")
|
||||
property string importStep3Desc: qsTr("Select \"Link another device\"")
|
||||
property string importStep4Desc: qsTr("The PIN code will be available for 10 minutes")
|
||||
property string importFromDeviceDescription: qsTr("A PIN code is required to use an existing Jami account on this device.")
|
||||
property string importStep1: qsTr("Step 1")
|
||||
property string importStep2: qsTr("Step 2")
|
||||
property string importStep3: qsTr("Step 3")
|
||||
property string importStep4: qsTr("Step 4")
|
||||
property string importStep1Desc: qsTr("Go to the account management settings of a previous device.")
|
||||
property string importStep2Desc: qsTr("Choose the account to link.")
|
||||
property string importStep3Desc: qsTr("Select “Link another device.”")
|
||||
property string importStep4Desc: qsTr("The PIN code will expire in 10 minutes.")
|
||||
property string importPasswordDesc: qsTr("Fill if the account is password-encrypted.")
|
||||
|
||||
// LinkDevicesDialog
|
||||
property string pinTimerInfos: qsTr("The PIN and the account password should be entered in your device within 10 minutes.")
|
||||
property string pinTimerInfos: qsTr("The PIN code and the account password should be entered in your device within 10 minutes.")
|
||||
property string close: qsTr("Close")
|
||||
property string enterAccountPassword: qsTr("Enter account password")
|
||||
property string enterPasswordPinCode: qsTr("This account is password encrypted, enter the password to generate a PIN code.")
|
||||
property string addDevice: qsTr("Add Device")
|
||||
property string pinExpired: qsTr("PIN expired")
|
||||
property string pinExpired: qsTr("PIN code has expired.")
|
||||
property string onAnotherDevice: qsTr("On another device")
|
||||
property string onAnotherDeviceInstruction: qsTr("Install and launch Jami, select \"Import from another device\" and scan the QR code.")
|
||||
property string onAnotherDeviceInstruction: qsTr("Install and launch Jami, select “Import from another device” and scan the QR code.")
|
||||
property string linkNewDevice: qsTr("Link new device")
|
||||
property string linkingInstructions: qsTr("In Jami, scan QR code or manually enter the PIN.")
|
||||
property string pinValidity: qsTr("The PIN code is valid for: ")
|
||||
property string linkingInstructions: qsTr("In Jami, scan QR code or manually enter PIN code.")
|
||||
property string pinValidity: qsTr("The PIN code will expire in: ")
|
||||
|
||||
// PasswordDialog
|
||||
property string enterPassword: qsTr("Enter password")
|
||||
@ -611,14 +611,14 @@ Item {
|
||||
property string exportAccount: qsTr("Export")
|
||||
|
||||
// PhotoBoothView
|
||||
property string selectAvatarImage: qsTr("Select image as avatar")
|
||||
property string selectImage: qsTr("Select image")
|
||||
property string importFromFile: qsTr("Import avatar from image file")
|
||||
property string removeImage: qsTr("Remove image")
|
||||
property string selectProfilePicture: qsTr("Select image as profile picture")
|
||||
property string selectImage: qsTr("How do you want to set the profile picture?")
|
||||
property string importFromFile: qsTr("Import profile picture from image file")
|
||||
property string removeImage: qsTr("Remove profile picture")
|
||||
property string takePhoto: qsTr("Take photo")
|
||||
property string imageFiles: qsTr("Image Files (*.jpeg *.jpg *.png *.JPEG* .JPG *.PNG)")
|
||||
property string imageFiles: qsTr("Image files (*.jpeg *.jpg *.png *.JPEG* .JPG *.PNG)")
|
||||
|
||||
// Plugins
|
||||
// Extensions
|
||||
property string autoUpdate: qsTr("Auto update")
|
||||
property string disableAll: qsTr("Disable all")
|
||||
property string installed: qsTr("Installed")
|
||||
@ -626,33 +626,34 @@ Item {
|
||||
property string installing: qsTr("Installing")
|
||||
property string installManually: qsTr("Install manually")
|
||||
property string installMannuallyDescription: qsTr("Install an extension directly from your device.")
|
||||
property string pluginStoreTitle: qsTr("Available")
|
||||
property string pluginStoreNotAvailable: qsTr("Plugins store is not available")
|
||||
property string storeNotSupportedPlatform: qsTr("The Jami Extension Store currently has no extension available for the platform in use. Check again later!")
|
||||
property string pluginPreferences: qsTr("Preferences")
|
||||
property string installationFailed: qsTr("Installation failed")
|
||||
property string pluginInstallationFailed: qsTr("The installation of the plugin failed")
|
||||
property string extensionStoreTitle: qsTr("Available")
|
||||
property string extensionStoreNotAvailable: qsTr("The Jami Extension Store is not currently available. Please try again later.")
|
||||
property string storeNotSupportedPlatform: qsTr("There are no extensions currently available in the Jami Extension Store for the platform in use. Please check again later.")
|
||||
property string extensionPreferences: qsTr("Preferences")
|
||||
property string installationFailed: qsTr("Installation error")
|
||||
property string extensionInstallationFailed: qsTr("An error occurred while installing the extension.")
|
||||
property string reset: qsTr("Reset")
|
||||
property string uninstall: qsTr("Uninstall")
|
||||
property string resetPreferences: qsTr("Reset Preferences")
|
||||
property string selectPluginInstall: qsTr("Select a plugin to install")
|
||||
property string uninstallPlugin: qsTr("Uninstall plugin")
|
||||
property string pluginResetConfirmation: qsTr("Are you sure you wish to reset %1 preferences?")
|
||||
property string pluginUninstallConfirmation: qsTr("Are you sure you wish to uninstall %1?")
|
||||
property string goBackToPluginsList: qsTr("Go back to plugins list")
|
||||
property string selectFile: qsTr("Select a file")
|
||||
property string selectExtensionInstall: qsTr("Select extension to install")
|
||||
property string uninstallExtension: qsTr("Uninstall extension")
|
||||
property string confirmExtensionReset: qsTr("Do you really want to reset the preferences for the %1 extension?")
|
||||
property string confirmExtensionUninstall: qsTr("Do you really want to uninstall the %1 extension?")
|
||||
property string goBackToExtensionsList: qsTr("Go back to extensions list")
|
||||
property string selectFile: qsTr("Select file")
|
||||
property string select: qsTr("Select")
|
||||
property string chooseImageFile: qsTr("Choose image file")
|
||||
property string pluginFiles: qsTr("Plugin Files (*.jpl)")
|
||||
property string extensionFiles: qsTr("Extension files (*.jpl)")
|
||||
property string loadUnload: qsTr("Load/Unload")
|
||||
property string selectAnImage: qsTr("Select An Image to %1")
|
||||
property string editPreference: qsTr("Edit preference")
|
||||
property string onOff: qsTr("On/Off")
|
||||
property string choosePlugin: qsTr("Choose Plugin")
|
||||
property string versionPlugin: qsTr("Version %1")
|
||||
property string chooseExtension: qsTr("Choose extension")
|
||||
property string versionExtension: qsTr("Version %1")
|
||||
property string lastUpdate: qsTr("Last update %1")
|
||||
property string by: qsTr("By %1")
|
||||
property string proposedBy: qsTr("Proposed by %1")
|
||||
|
||||
// ProfilePage
|
||||
property string information: qsTr("Information")
|
||||
property string moreInformation: qsTr("More information")
|
||||
@ -662,9 +663,9 @@ Item {
|
||||
property string confirmRemovalRequest: qsTr("Enter the account password to confirm the removal of this device")
|
||||
|
||||
// SelectScreen
|
||||
property string selectScreen: qsTr("Select a screen to share")
|
||||
property string selectWindow: qsTr("Select a window to share")
|
||||
property string allScreens: qsTr("All Screens")
|
||||
property string selectScreen: qsTr("Select screen to share")
|
||||
property string selectWindow: qsTr("Select window to share")
|
||||
property string allScreens: qsTr("All screens")
|
||||
property string screens: qsTr("Screens")
|
||||
property string windows: qsTr("Windows")
|
||||
property string screen: qsTr("Screen %1")
|
||||
@ -682,7 +683,7 @@ Item {
|
||||
property string connectJAMSServer: qsTr("Connect to a JAMS server")
|
||||
property string createFromJAMS: qsTr("Create account from Jami Account Management Server (JAMS)")
|
||||
property string addSIPAccount: qsTr("Configure a SIP account")
|
||||
property string errorCreateAccount: qsTr("Error while creating your account. Check your credentials.")
|
||||
property string errorCreateAccount: qsTr("An error occurred while creating the account. Check credentials and try again.")
|
||||
property string createNewRV: qsTr("Create a rendezvous point")
|
||||
property string joinJami: qsTr("Join Jami")
|
||||
property string createNewJamiAccount: qsTr("Create new Jami account")
|
||||
@ -694,9 +695,9 @@ Item {
|
||||
property string welcomeToJami: qsTr("Welcome to Jami")
|
||||
|
||||
// SmartList
|
||||
property string clearText: qsTr("Clear Text")
|
||||
property string clearText: qsTr("Clear text")
|
||||
property string conversations: qsTr("Conversations")
|
||||
property string searchResults: qsTr("Search Results")
|
||||
property string searchResults: qsTr("Search results")
|
||||
|
||||
// SmartList context menu
|
||||
property string declineContactRequest: qsTr("Decline contact request")
|
||||
@ -706,15 +707,16 @@ Item {
|
||||
property string update: qsTr("Automatically check for updates")
|
||||
|
||||
// Generic dialog options
|
||||
property string optionOk: qsTr("Ok")
|
||||
property string optionOk: qsTr("OK")
|
||||
property string optionSave: qsTr("Save")
|
||||
property string optionCancel: qsTr("Cancel")
|
||||
property string optionUpgrade: qsTr("Upgrade")
|
||||
property string optionLater: qsTr("Later")
|
||||
property string optionDelete: qsTr("Delete")
|
||||
property string optionRemove: qsTr("Remove")
|
||||
property string optionLeave: qsTr("Leave")
|
||||
property string optionBlock: qsTr("Block")
|
||||
property string optionUnban: qsTr("Unban")
|
||||
property string optionUnblock: qsTr("Unblock")
|
||||
|
||||
// Conference moderation
|
||||
property string setModerator: qsTr("Set moderator")
|
||||
@ -735,8 +737,8 @@ Item {
|
||||
property string removeDefaultModerator: qsTr("Remove default moderator")
|
||||
|
||||
// Daemon reconnection
|
||||
property string reconnectDaemon: qsTr("Trying to reconnect to the Jami daemon (jamid)…")
|
||||
property string reconnectionFailed: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
|
||||
property string reconnectDaemon: qsTr("Attempting to reconnect to the Jami daemon (jamid)…")
|
||||
property string reconnectionFailed: qsTr("An error occurred while reconnecting to the Jami daemon (jamid).\nThe application will now exit.")
|
||||
|
||||
// Message view
|
||||
property string addEmoji: qsTr("Add emoji")
|
||||
@ -774,12 +776,12 @@ Item {
|
||||
property string edit: qsTr("Edit")
|
||||
property string edited: qsTr("Edited")
|
||||
property string joinCall: qsTr("Join call")
|
||||
property string joinInAudio: qsTr("Join in audio")
|
||||
property string joinInVideo: qsTr("Join in video")
|
||||
property string joinWithAudio: qsTr("Join with audio")
|
||||
property string joinWithVideo: qsTr("Join with video")
|
||||
property string startedACall: qsTr("Started a call")
|
||||
property string wantToJoin: qsTr("A call is in progress. Do you want to join the call?")
|
||||
property string needsHost: qsTr("Current host for this swarm seems unreachable. Do you want to host the call?")
|
||||
property string selectHost: qsTr("Select dedicated device for hosting future calls in this swarm. If not set, the host will be the device starting a call.")
|
||||
property string needsHost: qsTr("Current host for this group conversation seems unreachable. Do you want to host the call?")
|
||||
property string selectHost: qsTr("Select dedicated device for hosting future calls in this group conversation. If not set, the host will be the device starting a call.")
|
||||
property string selectThisDevice: qsTr("Select this device")
|
||||
property string selectDevice: qsTr("Select device")
|
||||
property string removeCurrentDevice: qsTr("Remove current device")
|
||||
@ -790,28 +792,27 @@ Item {
|
||||
property string hideLocalVideo: qsTr("Hide local video")
|
||||
|
||||
// Invitation View
|
||||
property string invitationViewSentRequest: qsTr("%1 has sent you a request for a conversation.")
|
||||
property string invitationViewJoinConversation: qsTr("Hello,\nWould you like to join the conversation?")
|
||||
property string invitationViewAcceptedConversation: qsTr("You have accepted\nthe conversation request")
|
||||
property string invitationViewSentRequest: qsTr("%1 sent you a conversation invitation.")
|
||||
property string invitationViewJoinConversation: qsTr("Hello,\nDo you want to join this conversation?")
|
||||
property string invitationViewAcceptedConversation: qsTr("You have accepted\nthe conversation invitation.")
|
||||
property string invitationViewWaitingForSync: qsTr("Waiting until %1\nconnects to synchronize the conversation.")
|
||||
|
||||
// SwarmDetailsPanel
|
||||
// SwarmDetailsPanel (group conversation panel)
|
||||
property string members: qsTr("%1 Members")
|
||||
property string member: qsTr("Member")
|
||||
property string swarmName: qsTr("Swarm's name")
|
||||
property string contactName: qsTr("Contact's name")
|
||||
property string addADescription: qsTr("Add a description")
|
||||
property string groupName: qsTr("Group name")
|
||||
property string contactName: qsTr("Contact name")
|
||||
property string addDescription: qsTr("Add description")
|
||||
|
||||
property string muteConversation: qsTr("Mute conversation")
|
||||
property string ignoreNotificationsTooltip: qsTr("Ignore all notifications from this conversation")
|
||||
property string chooseAColor: qsTr("Choose a color")
|
||||
property string chooseAColor: qsTr("Color")
|
||||
property string defaultCallHost: qsTr("Default host (calls)")
|
||||
property string leaveConversation: qsTr("Leave conversation")
|
||||
property string typeOfSwarm: qsTr("Type of swarm")
|
||||
property string typeOfSwarm: qsTr("Type")
|
||||
property string none: qsTr("None")
|
||||
|
||||
// NewSwarmPage
|
||||
property string createTheSwarm: qsTr("Create the swarm")
|
||||
// NewSwarmPage (new group conversation page)
|
||||
property string goToConversation: qsTr("Go to conversation")
|
||||
property string kickMember: qsTr("Kick member")
|
||||
property string reinstateMember: qsTr("Reinstate member")
|
||||
@ -864,20 +865,20 @@ Item {
|
||||
property string theme: qsTr("Theme")
|
||||
property string zoomLevel: qsTr("Text zoom level")
|
||||
|
||||
//Donation campaign
|
||||
// Donation campaign
|
||||
property string donationTipBoxText: qsTr("Free and private sharing. <a href=\"https://jami.net/whydonate/\">Donate</a> to expand it.")
|
||||
property string donation: qsTr("Donate")
|
||||
property string donationText: qsTr("If you enjoy using Jami and believe in our mission, would you make a donation?")
|
||||
property string notNow: qsTr("Not now")
|
||||
property string enableDonation: qsTr("Enable donation campaign")
|
||||
|
||||
//Chat setting page
|
||||
// Chat setting page
|
||||
property string enter: qsTr("Enter")
|
||||
property string shiftEnter: qsTr("Shift+Enter")
|
||||
property string textFormattingDescription: qsTr("Enter or Shift+Enter to insert a new line")
|
||||
property string textFormatting: qsTr("Text formatting")
|
||||
|
||||
//Connection monitoring
|
||||
// Connection monitoring
|
||||
property string connected: qsTr("Connected")
|
||||
property string connectingTLS: qsTr("Connecting TLS")
|
||||
property string connectingICE: qsTr("Connecting ICE")
|
||||
|
||||
@ -513,6 +513,9 @@ Item {
|
||||
// MessageBar
|
||||
property int messageBarMarginSize: 10
|
||||
property int messageBarMinimumWidth: 438
|
||||
property int showTypoSecondToggleWidth: 540
|
||||
property int messageBarMaximumHeight: 150
|
||||
property int messageBarMinimumHeight: 36
|
||||
|
||||
// InvitationView
|
||||
property real invitationViewAvatarSize: 112
|
||||
|
||||
@ -159,7 +159,7 @@ NetworkManager::downloadFile(const QUrl& url,
|
||||
if (!file->open(QIODevice::WriteOnly)) {
|
||||
Q_EMIT errorOccurred(GetError::ACCESS_DENIED);
|
||||
files_.remove(uuid);
|
||||
qWarning() << Q_FUNC_INFO << "Could not open file for writing";
|
||||
qWarning() << Q_FUNC_INFO << "An error occurred while opening file for writing.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -454,7 +454,7 @@ ScreenCastPortal::getPipewireFd()
|
||||
|
||||
g_main_loop_run(glib_main_loop);
|
||||
// The main loop will run until it's stopped by openPipewireRemote (if
|
||||
// all DBus method calls were successfully), abort (in case of error) or
|
||||
// all DBus method calls were successful), abort (in case of error) or
|
||||
// on_cancelled_callback (if a DBus request is cancelled).
|
||||
// In the latter two cases, pw_ctx->portal_error gets set to a nonzero value.
|
||||
if (portal_error)
|
||||
@ -512,9 +512,10 @@ ScreenCastPortal::~ScreenCastPortal()
|
||||
// file descriptor needs to be closed by the client.
|
||||
if (close(pipewireFd) != 0) {
|
||||
int err = errno;
|
||||
qWarning() << "Error while attempting to close PipeWire file descriptor: errno =" << err;
|
||||
qWarning() << "An error occurred while attempting to close PipeWire file descriptor: errno ="
|
||||
<< err;
|
||||
} else {
|
||||
qInfo() << "Successfully closed PipeWire file descriptor";
|
||||
qInfo() << "PipeWire file descriptor closed successfully.";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -88,7 +88,7 @@ SidePanelBase {
|
||||
"visible": AppVersionManager.isUpdaterEnabled()
|
||||
}]
|
||||
}, {
|
||||
"title": JamiStrings.audioVideoSettingsTitle,
|
||||
"title": JamiStrings.mediaSettingsTitle,
|
||||
"icon": JamiResources.media_black_24dp_svg,
|
||||
"first": 12,
|
||||
"last": 14,
|
||||
@ -103,13 +103,13 @@ SidePanelBase {
|
||||
"title": JamiStrings.screenSharing
|
||||
}]
|
||||
}, {
|
||||
"title": JamiStrings.pluginSettingsTitle,
|
||||
"title": JamiStrings.extensionSettingsTitle,
|
||||
"icon": JamiResources.plugins_24dp_svg,
|
||||
"first": 15,
|
||||
"last": 15,
|
||||
"children": [{
|
||||
"id": 15,
|
||||
"title": JamiStrings.pluginSettingsTitle
|
||||
"title": JamiStrings.extensionSettingsTitle
|
||||
}]
|
||||
}];
|
||||
} else {
|
||||
@ -160,7 +160,7 @@ SidePanelBase {
|
||||
"title": JamiStrings.troubleshootTitle
|
||||
}]
|
||||
}, {
|
||||
"title": JamiStrings.audioVideoSettingsTitle,
|
||||
"title": JamiStrings.mediaSettingsTitle,
|
||||
"icon": JamiResources.media_black_24dp_svg,
|
||||
"first": 12,
|
||||
"last": 14,
|
||||
@ -175,13 +175,13 @@ SidePanelBase {
|
||||
"title": JamiStrings.screenSharing
|
||||
}]
|
||||
}, {
|
||||
"title": JamiStrings.pluginSettingsTitle,
|
||||
"title": JamiStrings.extensionSettingsTitle,
|
||||
"icon": JamiResources.plugins_24dp_svg,
|
||||
"first": 15,
|
||||
"last": 15,
|
||||
"children": [{
|
||||
"id": 15,
|
||||
"title": JamiStrings.pluginSettingsTitle
|
||||
"title": JamiStrings.extensionSettingsTitle
|
||||
}]
|
||||
}];
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ ColumnLayout {
|
||||
contactName: ContactName
|
||||
contactID: ContactID
|
||||
|
||||
btnImgSource: JamiStrings.optionUnban
|
||||
btnImgSource: JamiStrings.optionUnblock
|
||||
btnToolTip: JamiStrings.reinstateContact
|
||||
|
||||
onClicked: bannedListWidget.currentIndex = index
|
||||
|
||||
@ -10,10 +10,10 @@ import "../../commoncomponents"
|
||||
ColumnLayout {
|
||||
function installPlugin() {
|
||||
var dlg = viewCoordinator.presentDialog(appWindow, "commoncomponents/JamiFileDialog.qml", {
|
||||
"title": JamiStrings.selectPluginInstall,
|
||||
"title": JamiStrings.selectExtensionInstall,
|
||||
"fileMode": JamiFileDialog.OpenFile,
|
||||
"folder": StandardPaths.writableLocation(StandardPaths.DownloadLocation),
|
||||
"nameFilters": [JamiStrings.pluginFiles, JamiStrings.allFiles]
|
||||
"nameFilters": [JamiStrings.extensionFiles, JamiStrings.allFiles]
|
||||
});
|
||||
dlg.fileAccepted.connect(function (file) {
|
||||
var url = UtilsAdapter.getAbsPath(file.toString());
|
||||
@ -29,7 +29,7 @@ ColumnLayout {
|
||||
function presentErrorMessage() {
|
||||
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
|
||||
"title": JamiStrings.installationFailed,
|
||||
"infoText": JamiStrings.pluginInstallationFailed,
|
||||
"infoText": JamiStrings.extensionInstallationFailed,
|
||||
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue],
|
||||
"buttonTitles": [JamiStrings.optionOk],
|
||||
"buttonCallBacks": [],
|
||||
|
||||
@ -53,7 +53,7 @@ BaseModalDialog {
|
||||
pinRectangle.visible = true
|
||||
exportedPIN.text = pin;
|
||||
} else {
|
||||
pinRectangle.success = false;
|
||||
infoLabel.success = false;
|
||||
infoLabel.visible = true;
|
||||
switch (status) {
|
||||
case NameDirectory.ExportOnRingStatus.WRONG_PASSWORD:
|
||||
|
||||
@ -44,7 +44,7 @@ ColumnLayout {
|
||||
} else {
|
||||
viewCoordinator.presentDialog(appWindow, "commoncomponents/SimpleMessageDialog.qml", {
|
||||
"title": JamiStrings.removeDevice,
|
||||
"infoText": JamiStrings.sureToRemoveDevice,
|
||||
"infoText": JamiStrings.confirmRemoveDevice,
|
||||
"buttonTitles": [JamiStrings.optionOk, JamiStrings.optionCancel],
|
||||
"buttonStyles": [SimpleMessageDialog.ButtonStyle.TintedBlue, SimpleMessageDialog.ButtonStyle.TintedBlack],
|
||||
"buttonCallBacks": [function () {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user