mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-10-30 07:53:33 +08:00
Compare commits
118 Commits
nightly/20
...
beta/20241
| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| 3b9fb0bfca | |||
| 3673b0646c | |||
| 2e2f6423f8 | |||
| 28c1cbbb34 | |||
| 87c215deb7 | |||
| 77eddcd962 | |||
| 043a715c59 | |||
| 5bd3ead22d | |||
| a9aa1cac80 | |||
| 409ba70258 | |||
| dc50f19815 | |||
| d83895dcc9 | |||
| e24a3d6a4d | |||
| 06de33e1be | |||
| c8fbcd8c6b | |||
| 31269fe8fc | |||
| a676ad395a | |||
| 04c71d02e0 | |||
| 1fe60b9c33 | |||
| 51ef7a83da | |||
| 588a8abdac | |||
| 8a149b6c4f | |||
| 6105f4f7ce | |||
| 92341b27b6 | |||
| f39afdac4c | |||
| 690f2dd85c | |||
| bd45d6a406 | |||
| 5b92e4708a | |||
| 63c01f1439 | |||
| 73aeb02ebd | |||
| 9d91317089 | |||
| 474bc5f6a4 | |||
| f5b64e955b | |||
| b88627d125 | |||
| 200978a044 | |||
| a673ff9890 | |||
| 7803dd0991 | |||
| a8a736bc8c | |||
| ff7acf9932 | |||
| afde816b23 |
13
.gitignore
vendored
13
.gitignore
vendored
@ -1,9 +1,18 @@
|
||||
*.user
|
||||
doc/Doxyfile
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/**/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
**/.history
|
||||
|
||||
GeneratedFiles/
|
||||
.vs/
|
||||
.vscode/
|
||||
x64/
|
||||
x86/
|
||||
[wW]in32/
|
||||
|
||||
49
.vscode/launch.json
vendored
Normal file
49
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Jami-Client-Debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "",
|
||||
"linux":{
|
||||
"MIMode": "gdb",
|
||||
"program": "${workspaceFolder}/build/jami",
|
||||
"args": [
|
||||
"-d",
|
||||
],
|
||||
},
|
||||
"osx": {
|
||||
"MIMode": "lldb",
|
||||
"program": "${workspaceFolder}/build/Jami.app/Contents/MacOS/Jami",
|
||||
"environment": [
|
||||
{
|
||||
"name": "NO_COLOR",
|
||||
"value": "true",
|
||||
}
|
||||
],
|
||||
},
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "cmake-build",
|
||||
"externalConsole": false, // A macOS dev may want to set this to true.
|
||||
},
|
||||
{
|
||||
// Using this configuration will require manually reconfiguring the project using
|
||||
// build.py --no-libwrap, otherwise the daemon executable will not be built and the
|
||||
// client will not be built with ENABLE_LIBWRAP=False.
|
||||
"name": "Jami-Daemon-Debug",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"linux": {
|
||||
"MIMode": "gdb",
|
||||
"program": "${workspaceFolder}/daemon/bin/dbus/jamid",
|
||||
},
|
||||
"program": "",
|
||||
"args": [
|
||||
"-cdp",
|
||||
],
|
||||
"cwd": "${workspaceFolder}",
|
||||
"preLaunchTask": "cmake-build",
|
||||
}
|
||||
]
|
||||
}
|
||||
15
.vscode/settings.json
vendored
Normal file
15
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"C_Cpp.default.includePath": [
|
||||
"${default}",
|
||||
"${workspaceFolder}/**",
|
||||
"/usr/lib/libqt-jami/include/**",
|
||||
"/usr/lib64/qt-jami/include/**",
|
||||
],
|
||||
"C_Cpp.default.cppStandard": "c++17",
|
||||
"C_Cpp.default.cStandard": "c11",
|
||||
"cmake.configureOnOpen": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "xaver.clang-format",
|
||||
"files.eol": "\n",
|
||||
"cSpell.enabled": false,
|
||||
}
|
||||
93
.vscode/tasks.json
vendored
Normal file
93
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,93 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "run-tests",
|
||||
"type": "shell",
|
||||
"command": "ctest",
|
||||
"options": {
|
||||
"cwd": "${workspaceFolder}/build/tests",
|
||||
"env": {
|
||||
"HOME": "/tmp"
|
||||
}
|
||||
},
|
||||
"args": [
|
||||
"-V",
|
||||
"-R"
|
||||
],
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [],
|
||||
"detail": "Run the tests using CTest."
|
||||
},
|
||||
{
|
||||
"label": "cmake-configure",
|
||||
"type": "shell",
|
||||
"command": "cmake",
|
||||
"args": [
|
||||
"-S", ".",
|
||||
"-B", "build",
|
||||
"-DCMAKE_BUILD_TYPE=Debug",
|
||||
"-DCMAKE_PREFIX_PATH=\"/usr/lib64/qt-jami;/usr/lib/libqt-jami\"",
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "Generate the build system files with CMake."
|
||||
},
|
||||
{
|
||||
"label": "cmake-configure-tests",
|
||||
"type": "shell",
|
||||
"command": "cmake",
|
||||
"args": [
|
||||
"-S", ".",
|
||||
"-B", "build",
|
||||
"-DBUILD_TESTING=${input:buildTestingInput}"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "Generate the build system files with CMake."
|
||||
},
|
||||
{
|
||||
"label": "cmake-build",
|
||||
"type": "shell",
|
||||
"command": "cmake",
|
||||
"args": [
|
||||
"--build", "build",
|
||||
"-j$(nproc)",
|
||||
],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$gcc"
|
||||
],
|
||||
"detail": "Compile the project using the generated build system.",
|
||||
"dependsOn": [
|
||||
"cmake-configure"
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "cmake-clean",
|
||||
"type": "shell",
|
||||
"command": "rm",
|
||||
"args": [
|
||||
"-rf",
|
||||
"build"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": [],
|
||||
"detail": "Clean the build directory."
|
||||
}
|
||||
],
|
||||
"inputs": [
|
||||
{
|
||||
"id": "buildTestingInput",
|
||||
"type": "pickString",
|
||||
"description": "Do you want to enable testing?",
|
||||
"options": ["True", "False"],
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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
|
||||
@ -455,10 +475,12 @@ elseif (NOT APPLE)
|
||||
${APP_SRC_DIR}/xrectsel.c
|
||||
${APP_SRC_DIR}/connectivitymonitor.cpp
|
||||
${APP_SRC_DIR}/dbuserrorhandler.cpp
|
||||
${APP_SRC_DIR}/appversionmanager.cpp)
|
||||
${APP_SRC_DIR}/appversionmanager.cpp
|
||||
${APP_SRC_DIR}/screencastportal.cpp)
|
||||
list(APPEND COMMON_HEADERS
|
||||
${APP_SRC_DIR}/xrectsel.h
|
||||
${APP_SRC_DIR}/dbuserrorhandler.h)
|
||||
${APP_SRC_DIR}/dbuserrorhandler.h
|
||||
${APP_SRC_DIR}/screencastportal.h)
|
||||
list(APPEND QT_MODULES DBus)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
@ -473,6 +495,11 @@ elseif (NOT APPLE)
|
||||
add_definitions(${GIO_CFLAGS})
|
||||
endif()
|
||||
|
||||
pkg_check_modules(GIOUNIX REQUIRED gio-unix-2.0)
|
||||
if(GIOUNIX_FOUND)
|
||||
add_definitions(${GIOUNIX_CFLAGS})
|
||||
endif()
|
||||
|
||||
pkg_check_modules(LIBNM libnm)
|
||||
if(LIBNM_FOUND)
|
||||
add_definitions(-DUSE_LIBNM)
|
||||
@ -584,6 +611,7 @@ include_directories(
|
||||
if(ENABLE_LIBWRAP)
|
||||
list(APPEND COMMON_HEADERS
|
||||
${LIBCLIENT_SRC_DIR}/qtwrapper/instancemanager_wrap.h)
|
||||
add_definitions(-DENABLE_LIBWRAP=true)
|
||||
endif()
|
||||
|
||||
# SFPM
|
||||
@ -618,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()
|
||||
@ -811,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.
|
||||
@ -844,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
|
||||
|
||||
@ -288,7 +288,7 @@ Once the build has finished, you should then be able to use the Visual Studio So
|
||||
|
||||
**Set up**
|
||||
|
||||
- macOS minimum version 10.15
|
||||
- macOS minimum version 11.0
|
||||
- install python3
|
||||
- download xcode
|
||||
- install Qt 6.6
|
||||
|
||||
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: 8596d253a2...4197001925
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()
|
||||
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:20.04
|
||||
FROM ubuntu:22.04
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
ENV QT_QUICK_BACKEND software
|
||||
@ -10,7 +10,7 @@ RUN apt-get update && \
|
||||
|
||||
RUN apt install gnupg dirmngr ca-certificates curl --no-install-recommends
|
||||
RUN curl -s https://dl.jami.net/public-key.gpg | tee /usr/share/keyrings/jami-archive-keyring.gpg > /dev/null
|
||||
RUN sh -c "echo 'deb [signed-by=/usr/share/keyrings/jami-archive-keyring.gpg] https://dl.jami.net/internal/ubuntu_20.04/ jami main' > /etc/apt/sources.list.d/jami.list"
|
||||
RUN sh -c "echo 'deb [signed-by=/usr/share/keyrings/jami-archive-keyring.gpg] https://dl.jami.net/internal/ubuntu_22.04/ jami main' > /etc/apt/sources.list.d/jami.list"
|
||||
RUN apt-get update && apt-get install libqt-jami -y
|
||||
|
||||
RUN apt-get install -y -o Acquire::Retries=10 \
|
||||
@ -51,6 +51,7 @@ RUN apt-get install -y -o Acquire::Retries=10 \
|
||||
libswscale-dev \
|
||||
libavdevice-dev \
|
||||
libopus-dev \
|
||||
libpipewire-0.3-dev \
|
||||
libudev-dev \
|
||||
libgsm1-dev \
|
||||
libjsoncpp-dev \
|
||||
@ -65,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,11 +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 \
|
||||
|
||||
@ -100,6 +100,7 @@ RUN dnf install -y \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
python3-html5lib \
|
||||
cups-devel
|
||||
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"]
|
||||
@ -28,4 +28,10 @@ ADD extras/packaging/gnu-linux/scripts/install-cmake.sh /opt/install-cmake.sh
|
||||
RUN /opt/install-cmake.sh
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
|
||||
# Setting this variable so that FFmpeg gets built without pipewiregrab
|
||||
# (see daemon/contrib/bootstrap and daemon/contrib/src/ffmpeg/rules.mak)
|
||||
# We rely on PipeWire for screen sharing on Wayland, but the version available on Debian 11 is too old.
|
||||
ENV DISABLE_PIPEWIRE=true
|
||||
|
||||
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"]
|
||||
|
||||
@ -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"]
|
||||
|
||||
@ -98,6 +98,7 @@ RUN dnf install -y \
|
||||
clang \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
pipewire-devel \
|
||||
cups-devel #Chromium for Qt
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
|
||||
|
||||
@ -98,7 +98,8 @@ RUN dnf install -y \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
python3-html5lib \
|
||||
cups-devel
|
||||
cups-devel \
|
||||
pipewire-devel
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
|
||||
|
||||
|
||||
@ -97,7 +97,8 @@ RUN dnf install -y \
|
||||
cmake \
|
||||
fmt-devel \
|
||||
python3.10 \
|
||||
cups-devel
|
||||
cups-devel \
|
||||
pipewire-devel
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-rpm.sh
|
||||
|
||||
|
||||
105
extras/packaging/gnu-linux/docker/Dockerfile_fedora_40
Normal file
105
extras/packaging/gnu-linux/docker/Dockerfile_fedora_40
Normal file
@ -0,0 +1,105 @@
|
||||
FROM fedora:40
|
||||
|
||||
RUN dnf clean all
|
||||
RUN dnf update -y
|
||||
|
||||
RUN dnf install -y dnf-command\(builddep\) rpmdevtools && \
|
||||
dnf install -y mock
|
||||
|
||||
RUN dnf groupinstall -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 \
|
||||
clang \
|
||||
clang-devel \
|
||||
llvm-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 \
|
||||
clang \
|
||||
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"]
|
||||
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"]
|
||||
@ -99,7 +99,8 @@ RUN zypper --non-interactive install -y \
|
||||
gstreamer-plugins-bad-devel \
|
||||
gstreamer-plugins-base-devel \
|
||||
cmake \
|
||||
wget
|
||||
wget \
|
||||
pipewire-devel
|
||||
|
||||
# openSUSE Leap 15.4 comes with Python 3.6 by default,
|
||||
# but we need at least 3.7 to compile Qt 6.6.1
|
||||
@ -112,4 +113,10 @@ ADD extras/packaging/gnu-linux/scripts/build-package-rpm.sh /opt/build-package-r
|
||||
|
||||
ENV CC=gcc
|
||||
ENV CXX=g++
|
||||
|
||||
# Setting this variable so that FFmpeg gets built without pipewiregrab
|
||||
# (see daemon/contrib/bootstrap and daemon/contrib/src/ffmpeg/rules.mak)
|
||||
# We rely on PipeWire for screen sharing on Wayland, but the version available on openSUSE Leap 15.4 is too old.
|
||||
ENV DISABLE_PIPEWIRE=true
|
||||
|
||||
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 \
|
||||
@ -100,7 +100,8 @@ RUN zypper --non-interactive install -y \
|
||||
gstreamer-plugins-bad-devel \
|
||||
gstreamer-plugins-base-devel \
|
||||
cmake \
|
||||
wget
|
||||
wget \
|
||||
pipewire-devel
|
||||
|
||||
# openSUSE Leap 15.5 comes with Python 3.6 by default,
|
||||
# but we need at least 3.7 to compile Qt 6.6.1
|
||||
|
||||
@ -33,4 +33,10 @@ ADD extras/packaging/gnu-linux/scripts/install-cmake.sh /opt/install-cmake.sh
|
||||
RUN /opt/install-cmake.sh
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/build-package-debian.sh /opt/build-package-debian.sh
|
||||
|
||||
# Setting this variable so that FFmpeg gets built without pipewiregrab
|
||||
# (see daemon/contrib/bootstrap and daemon/contrib/src/ffmpeg/rules.mak)
|
||||
# We rely on PipeWire for screen sharing on Wayland, but the version available on Ubuntu 20.04 is too old.
|
||||
ENV DISABLE_PIPEWIRE=true
|
||||
|
||||
CMD ["/opt/build-package-debian.sh"]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
FROM ubuntu:23.04
|
||||
FROM ubuntu:24.04
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
@ -10,6 +10,9 @@ RUN apt-get update && \
|
||||
python-is-python3 \
|
||||
wget
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/install-gcc-debian.sh /opt/install-gcc-debian.sh
|
||||
RUN /opt/install-gcc-debian.sh 13
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/prebuild-package-debian.sh /opt/prebuild-package-debian.sh
|
||||
|
||||
COPY extras/packaging/gnu-linux/rules/debian-qt/control /tmp/builddeps/debian/control
|
||||
29
extras/packaging/gnu-linux/docker/Dockerfile_ubuntu_24.10
Normal file
29
extras/packaging/gnu-linux/docker/Dockerfile_ubuntu_24.10
Normal file
@ -0,0 +1,29 @@
|
||||
FROM ubuntu:24.10
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get clean
|
||||
RUN apt-get update && \
|
||||
apt-get install -y -o Acquire::Retries=10 \
|
||||
devscripts \
|
||||
equivs \
|
||||
python-is-python3 \
|
||||
wget
|
||||
|
||||
ADD extras/packaging/gnu-linux/scripts/prebuild-package-debian.sh /opt/prebuild-package-debian.sh
|
||||
|
||||
COPY extras/packaging/gnu-linux/rules/debian-qt/control /tmp/builddeps/debian/control
|
||||
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"]
|
||||
@ -92,6 +92,7 @@ Build-Depends: debhelper (>= 9),
|
||||
libgl1-mesa-dri,
|
||||
# pkg-kde-tools (>= 0.15.17~),
|
||||
python3:any,
|
||||
python3-bs4,
|
||||
python3-html5lib,
|
||||
# qtbase5-private-dev (>= 5.15.2+dfsg~),
|
||||
xauth <!nocheck>,
|
||||
|
||||
@ -0,0 +1,348 @@
|
||||
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 ++-----
|
||||
.../mojom/mojom/generate/translate_unittest.py | 4 ----
|
||||
.../tools/mojom/mojom/parse/ast_unittest.py | 6 ------
|
||||
.../mojom/parse/conditional_features_unittest.py | 8 ++------
|
||||
.../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 -----
|
||||
.../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 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 @@
|
||||
# found in the LICENSE file.
|
||||
|
||||
import errno
|
||||
-import imp
|
||||
import os.path
|
||||
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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
import os.path
|
||||
import shutil
|
||||
-import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from mojom import fileutil
|
||||
|
||||
-
|
||||
class FileUtilTest(unittest.TestCase):
|
||||
def testEnsureDirectoryExists(self):
|
||||
- """Test that EnsureDirectoryExists fuctions correctly."""
|
||||
+ """Test that EnsureDirectoryExists functions correctly."""
|
||||
|
||||
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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib.util
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
-
|
||||
def _GetDirAbove(dirname):
|
||||
"""Returns the directory "above" this file containing |dirname| (which must
|
||||
also be "above" this file)."""
|
||||
@@ -20,12 +19,11 @@ def _GetDirAbove(dirname):
|
||||
|
||||
|
||||
try:
|
||||
- imp.find_module("mojom")
|
||||
+ importlib.util.find_spec("mojom")
|
||||
except ImportError:
|
||||
sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib"))
|
||||
from mojom.generate import generator
|
||||
|
||||
-
|
||||
class StringManipulationTest(unittest.TestCase):
|
||||
"""generator contains some string utilities, this tests only those."""
|
||||
|
||||
@@ -69,6 +67,5 @@ class StringManipulationTest(unittest.TestCase):
|
||||
self.assertEquals("SNAKE_D3D11_CASE",
|
||||
generator.ToUpperSnakeCase("snakeD3d11Case"))
|
||||
|
||||
-
|
||||
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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
-import os.path
|
||||
-import sys
|
||||
import unittest
|
||||
|
||||
from mojom.generate import module as mojom
|
||||
from mojom.generate import translate
|
||||
from mojom.parse import ast
|
||||
|
||||
-
|
||||
class TranslateTest(unittest.TestCase):
|
||||
"""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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
-import os.path
|
||||
-import sys
|
||||
import unittest
|
||||
|
||||
from mojom.parse import ast
|
||||
|
||||
-
|
||||
class _TestNode(ast.NodeBase):
|
||||
"""Node type for tests."""
|
||||
|
||||
@@ -20,13 +16,11 @@ class _TestNode(ast.NodeBase):
|
||||
def __eq__(self, other):
|
||||
return super().__eq__(other) and self.value == other.value
|
||||
|
||||
-
|
||||
class _TestNodeList(ast.NodeListBase):
|
||||
"""Node list type for tests."""
|
||||
|
||||
_list_item_type = _TestNode
|
||||
|
||||
-
|
||||
class ASTTest(unittest.TestCase):
|
||||
"""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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib.util
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
-
|
||||
def _GetDirAbove(dirname):
|
||||
"""Returns the directory "above" this file containing |dirname| (which must
|
||||
also be "above" this file)."""
|
||||
@@ -18,9 +17,8 @@ def _GetDirAbove(dirname):
|
||||
if tail == dirname:
|
||||
return path
|
||||
|
||||
-
|
||||
try:
|
||||
- imp.find_module('mojom')
|
||||
+ importlib.util.find_spec("mojom")
|
||||
except ImportError:
|
||||
sys.path.append(os.path.join(_GetDirAbove('pylib'), 'pylib'))
|
||||
import mojom.parse.ast as ast
|
||||
@@ -29,7 +27,6 @@ import mojom.parse.parser as parser
|
||||
|
||||
ENABLED_FEATURES = frozenset({'red', 'green', 'blue'})
|
||||
|
||||
-
|
||||
class ConditionalFeaturesTest(unittest.TestCase):
|
||||
"""Tests |mojom.parse.conditional_features|."""
|
||||
|
||||
@@ -356,6 +353,5 @@ class ConditionalFeaturesTest(unittest.TestCase):
|
||||
conditional_features.RemoveDisabledDefinitions,
|
||||
definition, ENABLED_FEATURES)
|
||||
|
||||
-
|
||||
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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
import os.path
|
||||
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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
+import importlib.util
|
||||
import os.path
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
-
|
||||
def _GetDirAbove(dirname):
|
||||
"""Returns the directory "above" this file containing |dirname| (which must
|
||||
also be "above" this file)."""
|
||||
@@ -18,17 +17,15 @@ def _GetDirAbove(dirname):
|
||||
if tail == dirname:
|
||||
return path
|
||||
|
||||
-
|
||||
sys.path.insert(1, os.path.join(_GetDirAbove("mojo"), "third_party"))
|
||||
from ply import lex
|
||||
|
||||
try:
|
||||
- imp.find_module("mojom")
|
||||
+ importlib.util.find_spec("mojom")
|
||||
except ImportError:
|
||||
sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib"))
|
||||
import mojom.parse.lexer
|
||||
|
||||
-
|
||||
# This (monkey-patching LexToken to make comparison value-based) is evil, but
|
||||
# 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 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 @@
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
-import imp
|
||||
-import os.path
|
||||
-import sys
|
||||
import unittest
|
||||
|
||||
from mojom.parse import ast
|
||||
from mojom.parse import lexer
|
||||
from mojom.parse import parser
|
||||
|
||||
-
|
||||
class ParserTest(unittest.TestCase):
|
||||
"""Tests |parser.Parse()|."""
|
||||
|
||||
@@ -1375,6 +1371,5 @@ class ParserTest(unittest.TestCase):
|
||||
r" *associated\? MyInterface& a;$"):
|
||||
parser.Parse(source3, "my_file.mojom")
|
||||
|
||||
-
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
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
|
||||
|
||||
+if PY34:
|
||||
+ from importlib.util import spec_from_loader
|
||||
+else:
|
||||
+ spec_from_loader = None
|
||||
+
|
||||
|
||||
def _add_doc(func, doc):
|
||||
"""Add documentation to a function."""
|
||||
@@ -186,6 +191,11 @@ class _SixMetaPathImporter(object):
|
||||
return self
|
||||
return None
|
||||
|
||||
+ def find_spec(self, fullname, path, target=None):
|
||||
+ if fullname in self.known_modules:
|
||||
+ return spec_from_loader(fullname, self)
|
||||
+ return None
|
||||
+
|
||||
def __get_module(self, fullname):
|
||||
try:
|
||||
return self.known_modules[fullname]
|
||||
@@ -223,6 +233,12 @@ class _SixMetaPathImporter(object):
|
||||
return None
|
||||
get_source = get_code # same as get_code
|
||||
|
||||
+ def create_module(self, spec):
|
||||
+ return self.load_module(spec.name)
|
||||
+
|
||||
+ def exec_module(self, module):
|
||||
+ pass
|
||||
+
|
||||
_importer = _SixMetaPathImporter(__name__)
|
||||
|
||||
|
||||
--
|
||||
2.34.1
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
index 3488120543..120e47a76f 100644
|
||||
--- a/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
+++ b/qt3d/src/3rdparty/assimp/src/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
|
||||
@@ -472,7 +472,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
|
||||
}
|
||||
catch (const DeadlyImportError& e)
|
||||
{
|
||||
- if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
|
||||
+ if (!is64bits && (length > std::numeric_limits<uint32_t>::max())) {
|
||||
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
|
||||
}
|
||||
throw;
|
||||
@ -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
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
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,
|
||||
@ -45,6 +45,8 @@ Build-Depends: debhelper (>= 9),
|
||||
libvdpau-dev,
|
||||
libssl-dev,
|
||||
libargon2-dev | libargon2-0-dev,
|
||||
# TODO: remove libpipewire-0.2-dev once we stop supporting Ubuntu 20.04
|
||||
libpipewire-0.3-dev | libpipewire-0.2-dev,
|
||||
# other
|
||||
nasm,
|
||||
yasm,
|
||||
|
||||
@ -99,10 +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
|
||||
|
||||
@ -50,6 +50,7 @@ BuildRequires: libuuid-devel
|
||||
BuildRequires: libva-devel
|
||||
BuildRequires: libvdpau-devel
|
||||
BuildRequires: pcre-devel
|
||||
BuildRequires: pipewire-devel
|
||||
BuildRequires: uuid-devel
|
||||
BuildRequires: yaml-cpp-devel
|
||||
|
||||
|
||||
@ -16,6 +16,9 @@
|
||||
%define computed_job_count_ %(echo $(( %available_memory / %memory_required_per_core / %max_parallel_builds )))
|
||||
%define computed_job_count %max %computed_job_count_ 1
|
||||
%define job_count %min %cpu_count %computed_job_count
|
||||
# Exclude vendored Qt6 from dependency generator
|
||||
%define __provides_exclude_from ^%{_libdir}/qt-jami/.*$
|
||||
%define __requires_exclude ^libQt6.*$
|
||||
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
@ -26,6 +29,8 @@ License: GPLv3+
|
||||
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
|
||||
@ -61,6 +66,8 @@ This package contains Qt libraries for Jami.
|
||||
|
||||
%prep
|
||||
%setup -n qt-everywhere-src-%{version}
|
||||
%patch -P 0 -p1
|
||||
%patch -P 1 -p1
|
||||
|
||||
%build
|
||||
echo "Building Qt using %{job_count} parallel jobs"
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
%define version RELEASE_VERSION
|
||||
%define release 0
|
||||
|
||||
# Exclude vendored Qt6 from dependency generator
|
||||
%define __requires_exclude ^libQt6.*$
|
||||
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}%{?dist}
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
From 9721082687c9529fe6ae3c5304dcf079158e8a77 Mon Sep 17 00:00:00 2001
|
||||
From: Sam James <sam@gentoo.org>
|
||||
Date: Sun, 04 Jun 2023 04:15:16 +0100
|
||||
Subject: [PATCH] heap: Add missing <algorithm> include for std::remove
|
||||
|
||||
GCC 14 changes some internal includes within libstdc++ so this transient
|
||||
include gets lost. Include <algorithm> explicitly for std::remove.
|
||||
|
||||
Change-Id: Iab8a2c751a0f9c9dc6a770d6296ad6de724ef3bb
|
||||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4583222
|
||||
Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
|
||||
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
|
||||
Cr-Commit-Position: refs/heads/main@{#88037}
|
||||
---
|
||||
|
||||
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>
|
||||
@ -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
|
||||
|
||||
@ -138,6 +138,10 @@ apps:
|
||||
autostart: jami.desktop
|
||||
common-id: net.jami.Jami
|
||||
desktop: usr/share/applications/jami.desktop
|
||||
environment:
|
||||
PIPEWIRE_CONFIG_NAME: "$SNAP/usr/share/pipewire/pipewire.conf"
|
||||
PIPEWIRE_MODULE_DIR: "$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/pipewire-0.3"
|
||||
SPA_PLUGIN_DIR: "$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET/spa-0.2"
|
||||
slots:
|
||||
- dbus-jami
|
||||
- dbus-ring
|
||||
@ -168,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:
|
||||
@ -255,6 +259,8 @@ parts:
|
||||
sed -i -E 's|(tmpName) << (PACKAGE_NAME << "_shm_")|\1 << "snap.jami." << \2|' ./daemon/src/media/video/sinkclient.cpp
|
||||
sed -i -E 's|^Icon=.*|Icon=${SNAP}/usr/share/icons/hicolor/scalable/apps/jami.svg|' extras/data/jami.desktop
|
||||
override-build: |
|
||||
$SNAPCRAFT_PART_BUILD/extras/packaging/gnu-linux/scripts/install-pipewire-from-source.sh
|
||||
|
||||
cd $SNAPCRAFT_PART_BUILD/daemon/contrib
|
||||
mkdir -p native
|
||||
cd native
|
||||
@ -319,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
|
||||
|
||||
@ -44,6 +44,23 @@ QUILT_REFRESH_ARGS="-p 1"
|
||||
|
||||
if [ ! -f "${qt_deb_path}" ] || [ "${FORCE_REBUILD_QT}" = "true" ]; then
|
||||
(
|
||||
|
||||
# HACK: For now on ubuntu 24.04 there is no python3.10 package
|
||||
# So create a PyEnv environment to install the required packages
|
||||
if cat /etc/os-release | grep -Eq "24.04"; then
|
||||
apt-get install git gcc make python3-pip libssl-dev curl libreadline-dev -y
|
||||
curl https://pyenv.run | bash
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
eval "$(pyenv init -)"
|
||||
pyenv install 3.10.0
|
||||
pyenv local 3.10.0
|
||||
|
||||
python -m pip install html5lib
|
||||
python -m pip install six
|
||||
fi
|
||||
|
||||
|
||||
flock 9 # block until the lock file is gone
|
||||
test -f "${qt_deb_path}" && exit 0 # check again
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ rpmdev-setuptree
|
||||
|
||||
# Copy the source tarball.
|
||||
cp --reflink=auto "/src/$RELEASE_TARBALL_FILENAME" /root/rpmbuild/SOURCES
|
||||
cp patches/*.patch /root/rpmbuild/SOURCES/
|
||||
|
||||
QT_JAMI_PREFIX="/usr/lib64/qt-jami"
|
||||
PATH="${QT_JAMI_PREFIX}/bin:${PATH}"
|
||||
@ -43,7 +44,7 @@ PKG_CONFIG_PATH="${QT_JAMI_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
|
||||
CMAKE_PREFIX_PATH="${QT_JAMI_PREFIX}/lib/cmake:${CMAKE_PREFIX_PATH}"
|
||||
QT_MAJOR=6
|
||||
QT_MINOR=6
|
||||
QT_PATCH=1
|
||||
QT_PATCH=3
|
||||
QT_RELEASE_PATCH=0
|
||||
|
||||
QT_MAJOR_MINOR=${QT_MAJOR}.${QT_MINOR}
|
||||
@ -52,7 +53,7 @@ QT_MAJOR_MINOR_PATCH=${QT_MAJOR}.${QT_MINOR}.${QT_PATCH}
|
||||
QT_TARBALL_URL=https://download.qt.io/archive/qt/$QT_MAJOR_MINOR/\
|
||||
$QT_MAJOR_MINOR_PATCH/single/qt-everywhere-src-$QT_MAJOR_MINOR_PATCH.tar.xz
|
||||
|
||||
QT_TARBALL_SHA256="dd3668f65645fe270bc615d748bd4dc048bd17b9dc297025106e6ecc419ab95d"
|
||||
QT_TARBALL_SHA256="69d0348fef415da98aa890a34651e9cfb232f1bffcee289b7b4e21386bf36104"
|
||||
QT_TARBALL_FILE_NAME=$(basename "$QT_TARBALL_URL")
|
||||
CACHED_QT_TARBALL=$TARBALLS/$QT_TARBALL_FILE_NAME
|
||||
|
||||
@ -111,6 +112,10 @@ if [ ! -f "${RPM_PATH}" ]; then
|
||||
cp /root/rpmbuild/RPMS/x86_64/jami-libqt-$QT_MAJOR_MINOR_PATCH-*.fc38.x86_64.rpm "${RPM_PATH}"
|
||||
elif [[ "${DISTRIBUTION}" == "fedora_39" ]]; 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
|
||||
|
||||
35
extras/packaging/gnu-linux/scripts/install-pipewire-from-source.sh
Executable file
35
extras/packaging/gnu-linux/scripts/install-pipewire-from-source.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# The purpose of this script is to build PipeWire from source in a snap based on core20 / Ubuntu 20.04
|
||||
# It must be called in the "override-build" section of the relevant part in snapcraft.yaml
|
||||
|
||||
set -e
|
||||
|
||||
OLD_WD=$(pwd)
|
||||
cd /tmp
|
||||
|
||||
# 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
|
||||
tar xzf meson-0.61.1.tar.gz
|
||||
|
||||
# Build PipeWire 1.0.5 and install it in the /usr directory of the build environment
|
||||
wget -q https://gitlab.freedesktop.org/pipewire/pipewire/-/archive/1.0.5/pipewire-1.0.5.tar.gz
|
||||
echo "c5a5de26d684a1a84060ad7b6131654fb2835e03fccad85059be92f8e3ffe993 pipewire-1.0.5.tar.gz" | sha256sum --check
|
||||
tar xzf pipewire-1.0.5.tar.gz
|
||||
cd pipewire-1.0.5
|
||||
../meson-0.61.1/meson.py setup builddir -Dsession-managers=media-session -Dalsa=disabled -Dprefix=/usr
|
||||
../meson-0.61.1/meson.py compile -C builddir
|
||||
../meson-0.61.1/meson.py install -C builddir
|
||||
|
||||
# The files installed by the previous command are only for the "Build" step of the snap
|
||||
# creation process (https://snapcraft.io/docs/how-snapcraft-builds). In order to ensure
|
||||
# that PipeWire is installed in the final snap archive, we also need to copy all the
|
||||
# required files under the $SNAPCRAFT_PART_INSTALL directory.
|
||||
../meson-0.61.1/meson.py configure builddir -Dprefix=$SNAPCRAFT_PART_INSTALL/usr/
|
||||
../meson-0.61.1/meson.py install -C builddir
|
||||
|
||||
# Cleanup
|
||||
cd /tmp
|
||||
rm -rf meson-0.61.1 meson-0.61.1.tar.gz pipewire-1.0.5 pipewire-1.0.5.tar.gz
|
||||
cd $OLD_WD
|
||||
@ -34,7 +34,7 @@ cat << EOFILE > ${REPO_FOLDER}/${SPARKLE_FILE}
|
||||
<pubDate>$DATE_RFC2822</pubDate>
|
||||
<sparkle:version>${BUILD}</sparkle:version>
|
||||
<sparkle:shortVersionString>${VERSION}</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>10.15.0</sparkle:minimumSystemVersion>
|
||||
<sparkle:minimumSystemVersion>11.0</sparkle:minimumSystemVersion>
|
||||
<enclosure url="${REPO_URL}/$(basename ${PACKAGE})" type="application/octet-stream" $(./sign_update ${PACKAGE}) />
|
||||
</item>
|
||||
$(echo -e "${ITEMS}")
|
||||
|
||||
@ -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"
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.15</string>
|
||||
<string>11.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>${MACOSX_BUNDLE_BUNDLE_VERSION}</string>
|
||||
<key>LSApplicationCategoryType</key>
|
||||
|
||||
@ -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,10 +1,13 @@
|
||||
<h4 align="left"><span style="font-weight:600"> Created by</span></h4>
|
||||
<p>Adrien Béraud<br>
|
||||
<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>
|
||||
@ -17,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>
|
||||
@ -25,17 +27,23 @@ Emma Falkiewitz<br>
|
||||
Emmanuel Lepage-Vallée<br>
|
||||
Fadi Shehadeh<br>
|
||||
Franck Laurent<br>
|
||||
François-Simon Fauteux-Chapleau<br>
|
||||
Frédéric Guimont<br>
|
||||
Guillaume Heller<br>
|
||||
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>
|
||||
@ -55,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>
|
||||
@ -62,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
|
||||
|
||||
@ -116,7 +116,8 @@ ApplicationWindow {
|
||||
function close(force = false) {
|
||||
// If we're in the onboarding wizard or 'MinimizeOnClose'
|
||||
// is set, then we can quit
|
||||
if (force || !UtilsAdapter.getAppValue(Settings.MinimizeOnClose) || !UtilsAdapter.getAccountListSize()) {
|
||||
var minimizeToTray = UtilsAdapter.getAppValue(Settings.MinimizeOnClose) && UtilsAdapter.isSystemTrayIconVisible();
|
||||
if (force || !minimizeToTray || !UtilsAdapter.getAccountListSize()) {
|
||||
Qt.quit();
|
||||
} else {
|
||||
layoutManager.closeToTray();
|
||||
@ -361,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();
|
||||
}
|
||||
|
||||
@ -20,6 +20,8 @@
|
||||
|
||||
#include "appsettingsmanager.h"
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QLibraryInfo>
|
||||
|
||||
@ -101,7 +103,7 @@ AppSettingsManager::loadTranslations()
|
||||
installedTr_.clear();
|
||||
|
||||
QString locale_name = getLanguage();
|
||||
qDebug() << QString("Using locale: %1").arg(locale_name);
|
||||
C_INFO << QString("Using locale: %1").arg(locale_name);
|
||||
QString locale_lang = locale_name.split('_')[0];
|
||||
|
||||
QTranslator* qtTranslator_lang = new QTranslator(qApp);
|
||||
|
||||
@ -43,7 +43,7 @@ extern const QString defaultDownloadPath;
|
||||
|
||||
// Common key-value pairs for both APPSTORE and non-APPSTORE builds
|
||||
#define COMMON_KEYS \
|
||||
X(MinimizeOnClose, false) \
|
||||
X(MinimizeOnClose, true) \
|
||||
X(DownloadPath, defaultDownloadPath) \
|
||||
X(ScreenshotPath, {}) \
|
||||
X(EnableNotifications, true) \
|
||||
|
||||
@ -25,7 +25,11 @@
|
||||
#include "api/devicemodel.h"
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
#include "screencastportal.h"
|
||||
#include "xrectsel.h"
|
||||
#ifndef ENABLE_LIBWRAP
|
||||
#include <sys/prctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
@ -58,6 +62,12 @@ AvAdapter::AvAdapter(LRCInstance* instance, QObject* parent)
|
||||
&lrc::api::AVModel::onRendererFpsChange,
|
||||
this,
|
||||
&AvAdapter::updateRenderersFPSInfo);
|
||||
#ifdef Q_OS_LINUX
|
||||
connect(&lrcInstance_->behaviorController(),
|
||||
&BehaviorController::callStatusChanged,
|
||||
this,
|
||||
&AvAdapter::onCallStatusChanged);
|
||||
#endif
|
||||
}
|
||||
|
||||
// The top left corner of primary screen is (0, 0).
|
||||
@ -119,6 +129,93 @@ AvAdapter::shareEntireScreen(int screenNumber)
|
||||
->addMedia(callId, resource, lrc::api::CallModel::MediaRequestType::SCREENSHARING);
|
||||
}
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
static std::map<QString, std::unique_ptr<ScreenCastPortal>> callPortal;
|
||||
|
||||
void
|
||||
AvAdapter::onCallStatusChanged(const QString& accountId, const QString& callId)
|
||||
{
|
||||
auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
|
||||
auto& callModel = accInfo.callModel;
|
||||
const auto call = callModel->getCall(callId);
|
||||
|
||||
if (call.status == lrc::api::call::Status::ENDED) {
|
||||
closePortal(callId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::closePortal(const QString& callId)
|
||||
{
|
||||
if (callPortal.count(callId)) {
|
||||
lrcInstance_->avModel().stopPreview(callPortal[callId]->videoInputId);
|
||||
callPortal.erase(callId);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::shareWayland(bool entireScreen)
|
||||
{
|
||||
QString callId = lrcInstance_->getCurrentCallId();
|
||||
closePortal(callId);
|
||||
|
||||
PortalCaptureType captureType = entireScreen ? PortalCaptureType::SCREEN
|
||||
: PortalCaptureType::WINDOW;
|
||||
auto portal = std::make_unique<ScreenCastPortal>(captureType);
|
||||
|
||||
int err = portal->getPipewireFd();
|
||||
if (err == EACCES) {
|
||||
qInfo() << "Can't share screen: permission denied";
|
||||
return;
|
||||
} else if (err != 0) {
|
||||
qWarning() << "Failed to get PipeWire fd. Error code:" << err;
|
||||
return;
|
||||
}
|
||||
QString resource = QString("%1%2pipewire pid:%3 fd:%4 node:%5")
|
||||
.arg(libjami::Media::VideoProtocolPrefix::DISPLAY)
|
||||
.arg(libjami::Media::VideoProtocolPrefix::SEPARATOR)
|
||||
.arg(getpid())
|
||||
.arg(portal->pipewireFd)
|
||||
.arg(portal->pipewireNode);
|
||||
#ifndef ENABLE_LIBWRAP
|
||||
// If the daemon is running as a separate process, then it can't directly use the
|
||||
// PipeWire file descriptor opened by the client, so it will attempt to duplicate
|
||||
// it using the pidfd_getfd system call. This requires the daemon process to have
|
||||
// ptrace permission on the client process. On some systems, this will be true by
|
||||
// default (as long as the client and daemon processes have the same uid), but it
|
||||
// may not be if the Yama Linux Security Module is used. The call to prctl below
|
||||
// will grant permission if the Yama LSM is enabled and set to mode 1.
|
||||
//
|
||||
// References:
|
||||
// https://man7.org/linux/man-pages/man2/pidfd_getfd.2.html
|
||||
// https://man7.org/linux/man-pages/man2/prctl.2.html
|
||||
// https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/LSM/Yama.rst
|
||||
prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY);
|
||||
#endif
|
||||
// We open the video input here (instead of letting the daemon do it) to ensure
|
||||
// that the daemon doesn't try to restart it while we still need it, since this
|
||||
// would require getting a new file descriptor for PipeWire.
|
||||
portal->videoInputId = lrcInstance_->avModel().startPreview(resource);
|
||||
|
||||
callPortal[callId] = std::move(portal);
|
||||
muteCamera_ = !isCapturing();
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->addMedia(callId, resource, lrc::api::CallModel::MediaRequestType::SCREENSHARING);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::shareEntireScreenWayland()
|
||||
{
|
||||
shareWayland(true);
|
||||
}
|
||||
|
||||
void
|
||||
AvAdapter::shareWindowWayland()
|
||||
{
|
||||
shareWayland(false);
|
||||
}
|
||||
#endif // Q_OS_LINUX
|
||||
|
||||
void
|
||||
AvAdapter::shareAllScreens()
|
||||
{
|
||||
@ -204,10 +301,14 @@ AvAdapter::shareFile(const QString& filePath)
|
||||
&lrc::api::AVModel::fileOpened,
|
||||
this,
|
||||
[this, callId, filePath, resource](bool hasAudio, bool hasVideo) {
|
||||
lrcInstance_->avModel().setAutoRestart(resource, true);
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->addMedia(callId, filePath, lrc::api::CallModel::MediaRequestType::FILESHARING, false, hasAudio);
|
||||
lrcInstance_->avModel().pausePlayer(resource, false);
|
||||
lrcInstance_->avModel().setAutoRestart(resource, true);
|
||||
lrcInstance_->getCurrentCallModel()
|
||||
->addMedia(callId,
|
||||
filePath,
|
||||
lrc::api::CallModel::MediaRequestType::FILESHARING,
|
||||
false,
|
||||
hasAudio);
|
||||
lrcInstance_->avModel().pausePlayer(resource, false);
|
||||
});
|
||||
|
||||
lrcInstance_->avModel().createMediaPlayer(resource);
|
||||
@ -307,6 +408,9 @@ void
|
||||
AvAdapter::stopSharing(const QString& source)
|
||||
{
|
||||
auto callId = lrcInstance_->getCurrentCallId();
|
||||
#ifdef Q_OS_LINUX
|
||||
closePortal(callId);
|
||||
#endif
|
||||
if (!source.isEmpty() && !callId.isEmpty()) {
|
||||
if (source.startsWith(libjami::Media::VideoProtocolPrefix::DISPLAY)) {
|
||||
qDebug() << "Stopping display: " << source;
|
||||
|
||||
@ -69,9 +69,18 @@ protected:
|
||||
*/
|
||||
Q_INVOKABLE bool hasCamera() const;
|
||||
|
||||
// Share the screen specificed by screen number.
|
||||
// Share the screen specificed by screen number (all platforms except Wayland).
|
||||
Q_INVOKABLE void shareEntireScreen(int screenNumber);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// Share a screen on Wayland.
|
||||
// Sharing a screen on Wayland requires getting permission from the user. The logic for
|
||||
// this is handled by the ScreenCastPortal class using xdg-desktop-portal.
|
||||
// The choice of screen is also handled by xdg-desktop-portal, which is why we don't need
|
||||
// an argument for it (whereas we do on other platforms, cf. shareEntireScreen above).
|
||||
Q_INVOKABLE void shareEntireScreenWayland();
|
||||
#endif
|
||||
|
||||
// Share the all screens connected.
|
||||
Q_INVOKABLE void shareAllScreens();
|
||||
|
||||
@ -87,9 +96,18 @@ protected:
|
||||
// Select screen area to display (from all screens).
|
||||
Q_INVOKABLE void shareScreenArea(unsigned x, unsigned y, unsigned width, unsigned height);
|
||||
|
||||
// Select window to display.
|
||||
// Select window to display (all platforms except Wayland).
|
||||
Q_INVOKABLE void shareWindow(const QString& windowProcessId, const QString& windowId);
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// Share a window on Wayland.
|
||||
// Sharing a window on Wayland requires getting permission from the user. The logic for
|
||||
// this is handled by the ScreenCastPortal class using xdg-desktop-portal.
|
||||
// The choice of window is also handled by xdg-desktop-portal, which is why we don't need
|
||||
// arguments for it (whereas we do on other platforms, cf. shareWindow above).
|
||||
Q_INVOKABLE void shareWindowWayland();
|
||||
#endif
|
||||
|
||||
// Returns the screensharing resource
|
||||
Q_INVOKABLE QString getSharingResource(int screenId = -2,
|
||||
const QString& windowProcessId = "",
|
||||
@ -121,11 +139,25 @@ private Q_SLOTS:
|
||||
void onAudioDeviceEvent();
|
||||
void onRendererStarted(const QString& id, const QSize& size);
|
||||
void onRendererStopped(const QString& id);
|
||||
#ifdef Q_OS_LINUX
|
||||
// This function needs to be called whenever a screen/window share stops on Wayland.
|
||||
// Failure to do so can cause subsequent sharing attempts to fail.
|
||||
void closePortal(const QString& callId);
|
||||
|
||||
// On Wayland, we need to be informed of call status changes so that we can call
|
||||
// closePortal if a call ends while a screen/window share was in progress.
|
||||
void onCallStatusChanged(const QString& accountId, const QString& callId);
|
||||
#endif
|
||||
|
||||
private:
|
||||
// Get screens arrangement rect relative to primary screen.
|
||||
const QRect getAllScreensBoundingRect();
|
||||
|
||||
#ifdef Q_OS_LINUX
|
||||
// Used internally by shareEntireScreenWayland and shareWindowWayland
|
||||
void shareWayland(bool entireScreen);
|
||||
#endif
|
||||
|
||||
// Get the screen number
|
||||
int getScreenNumber(int screenId = 0) const;
|
||||
|
||||
|
||||
@ -354,10 +354,11 @@ CallAdapter::onCallInfosChanged(const QString& accountId, const QString& callId)
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::onCallAddedToConference(const QString& callId, const QString& confId)
|
||||
CallAdapter::onCallAddedToConference(const QString& callId, const QString& conversationId, const QString& confId)
|
||||
{
|
||||
Q_UNUSED(callId)
|
||||
Q_UNUSED(confId)
|
||||
Q_UNUSED(conversationId)
|
||||
saveConferenceSubcalls();
|
||||
}
|
||||
|
||||
@ -389,16 +390,13 @@ CallAdapter::hangUpACall(const QString& accountId, const QString& convUid)
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::setCallMedia(const QString& accountId, const QString& convUid, bool video)
|
||||
CallAdapter::setCallMedia(const QString& accountId, const QString& convUid, bool videoMuted)
|
||||
{
|
||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convUid, accountId);
|
||||
if (convInfo.uid.isEmpty())
|
||||
return;
|
||||
try {
|
||||
lrcInstance_->getAccountInfo(accountId).callModel->updateCallMediaList(convInfo.callId,
|
||||
video);
|
||||
} catch (...) {
|
||||
}
|
||||
|
||||
lrcInstance_->getAccountInfo(accountId).callModel->setVideoMuted(convInfo.callId, videoMuted);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -67,7 +67,7 @@ public:
|
||||
Q_INVOKABLE void placeAudioOnlyCall();
|
||||
Q_INVOKABLE void placeCall();
|
||||
Q_INVOKABLE void hangUpACall(const QString& accountId, const QString& convUid);
|
||||
Q_INVOKABLE void setCallMedia(const QString& accountId, const QString& convUid, bool video);
|
||||
Q_INVOKABLE void setCallMedia(const QString& accountId, const QString& convUid, bool videoMuted);
|
||||
Q_INVOKABLE void acceptACall(const QString& accountId, const QString& convUid);
|
||||
|
||||
Q_INVOKABLE void connectCallModel(const QString& accountId);
|
||||
@ -122,7 +122,7 @@ public Q_SLOTS:
|
||||
void onAccountChanged();
|
||||
void onCallStatusChanged(const QString& accountId, const QString& callId);
|
||||
void onCallStatusChanged(const QString& callId, int code);
|
||||
void onCallAddedToConference(const QString& callId, const QString& confId);
|
||||
void onCallAddedToConference(const QString& callId, const QString& conversationId, const QString& confId);
|
||||
void onCallStarted(const QString& callId);
|
||||
void onCallEnded(const QString& callId);
|
||||
void onCallInfosChanged(const QString& accountId, const QString& callId);
|
||||
|
||||
@ -362,36 +362,32 @@ CallOverlayModel::clearControls()
|
||||
}
|
||||
|
||||
void
|
||||
CallOverlayModel::registerFilter(QObject* object, QQuickItem* item)
|
||||
CallOverlayModel::setEventFilterActive(QObject* object, QQuickItem* item, bool isActive)
|
||||
{
|
||||
QQuickWindow* window = qobject_cast<QQuickWindow*>(object);
|
||||
if (!window || !item) {
|
||||
C_WARN << "Attempting to register an invalid object or item" << object << item;
|
||||
C_WARN << "Attempting to" << (isActive ? "register" : "unregister")
|
||||
<< "an invalid object or item" << window << item;
|
||||
return;
|
||||
}
|
||||
if (watchedItems_.contains(item)) {
|
||||
C_DBG << "Item already registered" << item;
|
||||
}
|
||||
watchedItems_.push_back(item);
|
||||
if (watchedItems_.size() == 1) {
|
||||
window->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CallOverlayModel::unregisterFilter(QObject* object, QQuickItem* item)
|
||||
{
|
||||
QQuickWindow* window = qobject_cast<QQuickWindow*>(object);
|
||||
if (!window || !item) {
|
||||
C_WARN << "Attempting to unregister an invalid object or item" << object << item;
|
||||
return;
|
||||
}
|
||||
if (!watchedItems_.contains(item)) {
|
||||
C_DBG << "Item not registered" << item;
|
||||
}
|
||||
watchedItems_.removeOne(item);
|
||||
if (watchedItems_.size() == 0) {
|
||||
window->removeEventFilter(this);
|
||||
if (isActive) {
|
||||
if (watchedItems_.contains(item)) {
|
||||
C_DBG << "Item already registered" << item;
|
||||
} else {
|
||||
watchedItems_.push_back(item);
|
||||
if (watchedItems_.size() == 1) {
|
||||
window->installEventFilter(this);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!watchedItems_.contains(item)) {
|
||||
C_DBG << "Item not registered" << item;
|
||||
} else {
|
||||
watchedItems_.removeOne(item);
|
||||
if (watchedItems_.size() == 0) {
|
||||
window->removeEventFilter(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -137,8 +137,7 @@ public:
|
||||
Q_INVOKABLE QVariant overflowHiddenModel();
|
||||
Q_INVOKABLE QVariant pendingConferenceesModel();
|
||||
|
||||
Q_INVOKABLE void registerFilter(QObject* object, QQuickItem* item);
|
||||
Q_INVOKABLE void unregisterFilter(QObject* object, QQuickItem* item);
|
||||
Q_INVOKABLE void setEventFilterActive(QObject* object, QQuickItem* item, bool isActive);
|
||||
bool eventFilter(QObject* object, QEvent* event) override;
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -1,83 +1,97 @@
|
||||
/*
|
||||
* 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 net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
// A SplitView that supports dynamic RTL and splitView state saving.
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
property bool isRTL: UtilsAdapter.isRTL
|
||||
property bool isSinglePane: false
|
||||
property bool isSwapped: false
|
||||
|
||||
onIsRTLChanged: {
|
||||
if (isRTL && isSinglePane && !isSwapped)
|
||||
return
|
||||
if ((isRTL && !isSwapped) || (!isRTL && isSwapped))
|
||||
swapItems()
|
||||
}
|
||||
onIsSinglePaneChanged: {
|
||||
if (isSwapped || isRTL)
|
||||
swapItems()
|
||||
}
|
||||
|
||||
property string splitViewStateKey: objectName
|
||||
property bool autoManageState: !(parent instanceof BaseView)
|
||||
|
||||
function saveSplitViewState() {
|
||||
UtilsAdapter.setAppValue("sv_" + splitViewStateKey, root.saveState());
|
||||
}
|
||||
|
||||
function restoreSplitViewState() {
|
||||
root.restoreState(UtilsAdapter.getAppValue("sv_" + splitViewStateKey));
|
||||
}
|
||||
|
||||
onResizingChanged: if (!resizing)
|
||||
saveSplitViewState()
|
||||
onVisibleChanged: {
|
||||
if (!autoManageState)
|
||||
return;
|
||||
visible ? restoreSplitViewState() : saveSplitViewState();
|
||||
}
|
||||
|
||||
function swapItems() {
|
||||
isSwapped = !isSwapped
|
||||
var qqci = children[0];
|
||||
if (qqci.children.length > 1) {
|
||||
// swap the children
|
||||
var tempPane = qqci.children[0];
|
||||
qqci.children[0] = qqci.children[1];
|
||||
qqci.children.push(tempPane);
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
visible: !isSinglePane
|
||||
implicitWidth: JamiTheme.splitViewHandlePreferredWidth
|
||||
implicitHeight: root.height
|
||||
color: JamiTheme.primaryBackgroundColor
|
||||
Rectangle {
|
||||
anchors.left: parent.left
|
||||
implicitWidth: 1
|
||||
implicitHeight: root.height
|
||||
color: JamiTheme.tabbarBorderColor
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 net.jami.Adapters 1.1
|
||||
import net.jami.Constants 1.1
|
||||
|
||||
// A SplitView that supports dynamic RTL and splitView state saving.
|
||||
SplitView {
|
||||
id: control
|
||||
|
||||
property bool isRTL: UtilsAdapter.isRTL
|
||||
property bool isSinglePane: false
|
||||
property bool isSwapped: false
|
||||
property real handleSize: 1
|
||||
|
||||
onIsRTLChanged: {
|
||||
if (isRTL && isSinglePane && !isSwapped)
|
||||
return
|
||||
if ((isRTL && !isSwapped) || (!isRTL && isSwapped))
|
||||
swapItems()
|
||||
}
|
||||
onIsSinglePaneChanged: {
|
||||
if (isSwapped || isRTL)
|
||||
swapItems()
|
||||
}
|
||||
|
||||
property string splitViewStateKey: objectName
|
||||
property bool autoManageState: !(parent instanceof BaseView)
|
||||
|
||||
function saveSplitViewState() {
|
||||
UtilsAdapter.setAppValue("sv_" + splitViewStateKey, control.saveState());
|
||||
}
|
||||
|
||||
function restoreSplitViewState() {
|
||||
control.restoreState(UtilsAdapter.getAppValue("sv_" + splitViewStateKey));
|
||||
}
|
||||
|
||||
onResizingChanged: if (!resizing)
|
||||
saveSplitViewState()
|
||||
onVisibleChanged: {
|
||||
if (!autoManageState)
|
||||
return;
|
||||
visible ? restoreSplitViewState() : saveSplitViewState();
|
||||
}
|
||||
|
||||
function swapItems() {
|
||||
isSwapped = !isSwapped
|
||||
var qqci = children[0];
|
||||
if (qqci.children.length > 1) {
|
||||
// swap the children
|
||||
var tempPane = qqci.children[0];
|
||||
qqci.children[0] = qqci.children[1];
|
||||
qqci.children.push(tempPane);
|
||||
}
|
||||
}
|
||||
|
||||
handle: Rectangle {
|
||||
id: handleRoot
|
||||
|
||||
readonly property int defaultSize: control.handleSize
|
||||
|
||||
implicitWidth: control.orientation === Qt.Horizontal ? handleRoot.defaultSize : control.width
|
||||
implicitHeight: control.orientation === Qt.Horizontal ? control.height : handleRoot.defaultSize
|
||||
|
||||
color: JamiTheme.tabbarBorderColor
|
||||
|
||||
containmentMask: Item {
|
||||
// In the default configuration, the total handle size is the sum of the default size of the
|
||||
// handle and the extra handle size (4). If the layout is not right-to-left (RTL), the handle
|
||||
// is positioned at 0 on the X-axis, otherwise it's positioned to the left by the extra handle
|
||||
// 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: !UtilsAdapter.isRTL ? 0 : -extraHandleSize
|
||||
readonly property real handleSize: handleRoot.defaultSize + extraHandleSize
|
||||
|
||||
x: control.orientation === Qt.Horizontal ? handleXPosition : 0
|
||||
width: control.orientation === Qt.Horizontal ? handleSize : handleRoot.width
|
||||
height: control.orientation === Qt.Horizontal ? handleRoot.height : handleSize
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,12 +28,14 @@ VideoView {
|
||||
crop: true
|
||||
visible: isRendering && visibilityCondition
|
||||
|
||||
Component.onDestruction: VideoDevices.stopDevice(rendererId);
|
||||
|
||||
function startWithId(id, force = false) {
|
||||
if (id !== undefined && id.length === 0) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
const forceRestart = rendererId === id;
|
||||
const forceRestart = rendererId === id || force;
|
||||
if (!forceRestart) {
|
||||
// Stop previous device
|
||||
VideoDevices.stopDevice(rendererId);
|
||||
|
||||
@ -164,7 +164,7 @@ BaseModalDialog {
|
||||
appWindow,
|
||||
"commoncomponents/JamiFileDialog.qml",
|
||||
{
|
||||
title: JamiStrings.selectAvatarImage,
|
||||
title: JamiStrings.selectProfilePicture,
|
||||
fileMode: JamiFileDialog.OpenFile,
|
||||
folder: StandardPaths.writableLocation(
|
||||
StandardPaths.PicturesLocation),
|
||||
|
||||
@ -278,7 +278,7 @@ 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
|
||||
|
||||
@ -299,24 +299,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: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || share.hovered || bgHandler.hovered)
|
||||
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(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || share.hovered || bgHandler.hovered));
|
||||
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 +332,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 +348,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: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || more.hovered || share.hovered || bgHandler.hovered)
|
||||
|
||||
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: CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || more.hovered || bgHandler.hovered)
|
||||
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(() => CurrentAccount.type !== Profile.Type.SIP && root.type !== Interaction.Type.CALL && Body !== "" && (bubbleArea.bubbleHovered || hovered || reply.hovered || more.hovered || bgHandler.hovered));
|
||||
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 +438,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 {
|
||||
@ -424,9 +480,9 @@ Control {
|
||||
id: editedRow
|
||||
anchors.left: root.bigMsg ? bubble.left : timestampItem.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: root.bigMsg || bubble.isDeleted ? 6 : 10
|
||||
anchors.bottomMargin: root.bigMsg ? 6 : 10
|
||||
anchors.leftMargin: root.bigMsg ? 10 : -timestampItem.width - 16
|
||||
visible: bubble.isEdited
|
||||
visible: bubble.isEdited && !bubble.isDeleted
|
||||
z: 1
|
||||
ResponsiveImage {
|
||||
id: editedImage
|
||||
@ -466,6 +522,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();
|
||||
}
|
||||
}
|
||||
@ -153,7 +153,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 +175,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 +198,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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <glib.h>
|
||||
#include <gio/gio.h>
|
||||
@ -171,10 +173,10 @@ static void
|
||||
logConnectionInfo(NMActiveConnection* connection)
|
||||
{
|
||||
if (connection) {
|
||||
qDebug() << "primary network connection:" << nm_active_connection_get_uuid(connection)
|
||||
<< "default: " << (nm_active_connection_get_default(connection) ? "yes" : "no");
|
||||
C_INFO << "primary network connection:" << nm_active_connection_get_uuid(connection)
|
||||
<< "default: " << (nm_active_connection_get_default(connection) ? "yes" : "no");
|
||||
} else {
|
||||
qWarning() << "no primary network connection detected, check network settings";
|
||||
C_WARN << "no primary network connection detected, check network settings";
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,11 +193,10 @@ nmClientCallback(G_GNUC_UNUSED GObject* source_object, GAsyncResult* result, Con
|
||||
{
|
||||
GError* error = nullptr;
|
||||
if (auto nm_client = nm_client_new_finish(result, &error)) {
|
||||
qDebug() << "NetworkManager client initialized, version: "
|
||||
<< nm_client_get_version(nm_client)
|
||||
<< ", daemon running:" << (nm_client_get_nm_running(nm_client) ? "yes" : "no")
|
||||
<< ", networking enabled:"
|
||||
<< (nm_client_networking_get_enabled(nm_client) ? "yes" : "no");
|
||||
C_INFO << "NetworkManager client initialized, version: " << nm_client_get_version(nm_client)
|
||||
<< ", daemon running:" << (nm_client_get_nm_running(nm_client) ? "yes" : "no")
|
||||
<< ", networking enabled:"
|
||||
<< (nm_client_networking_get_enabled(nm_client) ? "yes" : "no");
|
||||
|
||||
auto connection = nm_client_get_primary_connection(nm_client);
|
||||
logConnectionInfo(connection);
|
||||
@ -205,7 +206,7 @@ nmClientCallback(G_GNUC_UNUSED GObject* source_object, GAsyncResult* result, Con
|
||||
cm);
|
||||
|
||||
} else {
|
||||
qWarning() << "error initializing NetworkManager client: " << error->message;
|
||||
C_WARN << "error initializing NetworkManager client: " << error->message;
|
||||
g_clear_error(&error);
|
||||
}
|
||||
}
|
||||
@ -222,7 +223,7 @@ ConnectivityMonitor::ConnectivityMonitor(QObject* parent)
|
||||
|
||||
ConnectivityMonitor::~ConnectivityMonitor()
|
||||
{
|
||||
qDebug() << "Destroying connectivity monitor";
|
||||
C_DBG << "Destroying connectivity monitor";
|
||||
}
|
||||
|
||||
bool
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
#include "currentcall.h"
|
||||
|
||||
#include "callparticipantsmodel.h"
|
||||
#include "global.h"
|
||||
|
||||
#include <api/callparticipantsmodel.h>
|
||||
#include <api/devicemodel.h>
|
||||
@ -223,43 +224,14 @@ CurrentCall::updateCallInfo()
|
||||
set_isGrid(callInfo.layout == call::Layout::GRID);
|
||||
set_isAudioOnly(callInfo.isAudioOnly);
|
||||
|
||||
bool isAudioMuted {};
|
||||
bool isVideoMuted {};
|
||||
bool isSharing {};
|
||||
QString sharingSource {};
|
||||
bool isCapturing {};
|
||||
QString previewId {};
|
||||
using namespace libjami::Media;
|
||||
if (callInfo.status != lrc::api::call::Status::ENDED) {
|
||||
for (const auto& media : callInfo.mediaList) {
|
||||
if (media[MediaAttributeKey::MEDIA_TYPE] == Details::MEDIA_TYPE_VIDEO) {
|
||||
if (media[MediaAttributeKey::SOURCE].startsWith(VideoProtocolPrefix::DISPLAY)
|
||||
|| media[MediaAttributeKey::SOURCE].startsWith(VideoProtocolPrefix::FILE)) {
|
||||
isSharing = true;
|
||||
sharingSource = media[MediaAttributeKey::SOURCE];
|
||||
}
|
||||
if (media[MediaAttributeKey::ENABLED] == TRUE_STR
|
||||
&& media[MediaAttributeKey::MUTED] == FALSE_STR && previewId.isEmpty()) {
|
||||
previewId = media[libjami::Media::MediaAttributeKey::SOURCE];
|
||||
}
|
||||
if (media[libjami::Media::MediaAttributeKey::SOURCE].startsWith(
|
||||
libjami::Media::VideoProtocolPrefix::CAMERA)) {
|
||||
isVideoMuted |= media[MediaAttributeKey::MUTED] == TRUE_STR;
|
||||
isCapturing = media[MediaAttributeKey::MUTED] == FALSE_STR;
|
||||
}
|
||||
} else if (media[MediaAttributeKey::MEDIA_TYPE] == Details::MEDIA_TYPE_AUDIO) {
|
||||
if (media[MediaAttributeKey::LABEL] == "audio_0") {
|
||||
isAudioMuted |= media[libjami::Media::MediaAttributeKey::MUTED] == TRUE_STR;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
set_previewId(previewId);
|
||||
set_isAudioMuted(isAudioMuted);
|
||||
set_isVideoMuted(isVideoMuted);
|
||||
set_isSharing(isSharing);
|
||||
set_sharingSource(sharingSource);
|
||||
set_isCapturing(isCapturing);
|
||||
auto callInfoEx = callInfo.getCallInfoEx();
|
||||
set_previewId(callInfoEx["preview_id"].toString());
|
||||
set_isAudioMuted(callInfoEx["is_audio_muted"].toBool());
|
||||
set_isVideoMuted(callInfoEx["is_video_muted"].toBool());
|
||||
set_isSharing(callInfoEx["is_sharing"].toBool());
|
||||
set_sharingSource(isSharing_ ? callInfoEx["preview_id"].toString() : QString());
|
||||
set_isCapturing(callInfoEx["is_capturing"].toBool());
|
||||
|
||||
set_isHandRaised(callModel->isHandRaised(id_));
|
||||
set_isModerator(callModel->isModerator(id_));
|
||||
|
||||
@ -377,7 +349,7 @@ CurrentCall::onCurrentAccountIdChanged()
|
||||
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||
set_isSIP(accInfo.profileInfo.type == profile::Type::SIP);
|
||||
} catch (const std::exception& e) {
|
||||
qWarning() << "Can't update current call type" << e.what();
|
||||
C_DBG << "Can't update current call type" << e.what();
|
||||
}
|
||||
|
||||
connectModel();
|
||||
|
||||
@ -18,6 +18,8 @@
|
||||
|
||||
#include "currentconversation.h"
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#include <api/conversationmodel.h>
|
||||
#include <api/contact.h>
|
||||
|
||||
@ -264,51 +266,39 @@ void
|
||||
CurrentConversation::connectModel()
|
||||
{
|
||||
membersModel_->setMembers({}, {}, {});
|
||||
auto convModel = lrcInstance_->getCurrentConversationModel();
|
||||
if (!convModel)
|
||||
|
||||
auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
|
||||
auto currentCallModel = lrcInstance_->getCurrentCallModel();
|
||||
if (!currentConversationModel || !currentCallModel) {
|
||||
C_DBG << "CurrentConversation: can't connect to unavailable models";
|
||||
return;
|
||||
}
|
||||
|
||||
auto connectObjectSignal = [this](auto obj, auto signal, auto slot) {
|
||||
connect(obj, signal, this, slot, Qt::UniqueConnection);
|
||||
};
|
||||
|
||||
connectObjectSignal(convModel,
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::conversationUpdated,
|
||||
&CurrentConversation::onConversationUpdated);
|
||||
connectObjectSignal(convModel,
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::profileUpdated,
|
||||
&CurrentConversation::updateProfile);
|
||||
|
||||
connect(lrcInstance_->getCurrentConversationModel(),
|
||||
&ConversationModel::profileUpdated,
|
||||
this,
|
||||
&CurrentConversation::updateProfile,
|
||||
Qt::UniqueConnection);
|
||||
connect(lrcInstance_->getCurrentConversationModel(),
|
||||
&ConversationModel::onConversationErrorsUpdated,
|
||||
this,
|
||||
&CurrentConversation::updateErrors,
|
||||
Qt::UniqueConnection);
|
||||
connect(lrcInstance_->getCurrentConversationModel(),
|
||||
&ConversationModel::activeCallsChanged,
|
||||
this,
|
||||
&CurrentConversation::updateActiveCalls,
|
||||
Qt::UniqueConnection);
|
||||
connect(lrcInstance_->getCurrentConversationModel(),
|
||||
&ConversationModel::conversationPreferencesUpdated,
|
||||
this,
|
||||
&CurrentConversation::updateConversationPreferences,
|
||||
Qt::UniqueConnection);
|
||||
connect(lrcInstance_->getCurrentConversationModel(),
|
||||
&ConversationModel::needsHost,
|
||||
this,
|
||||
&CurrentConversation::onNeedsHost,
|
||||
Qt::UniqueConnection);
|
||||
connect(lrcInstance_->getCurrentCallModel(),
|
||||
&CallModel::callStatusChanged,
|
||||
this,
|
||||
&CurrentConversation::onCallStatusChanged,
|
||||
Qt::UniqueConnection);
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::conversationErrorsUpdated,
|
||||
&CurrentConversation::updateErrors);
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::activeCallsChanged,
|
||||
&CurrentConversation::updateActiveCalls);
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::conversationPreferencesUpdated,
|
||||
&CurrentConversation::updateConversationPreferences);
|
||||
connectObjectSignal(currentConversationModel,
|
||||
&ConversationModel::needsHost,
|
||||
&CurrentConversation::onNeedsHost);
|
||||
connectObjectSignal(currentCallModel,
|
||||
&CallModel::callStatusChanged,
|
||||
&CurrentConversation::onCallStatusChanged);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -162,6 +162,8 @@ MainApplication::MainApplication(int& argc, char** argv)
|
||||
"libclient.debug=false\n"
|
||||
"qt.*=false\n"
|
||||
"qml.debug=false\n"
|
||||
"default.debug=false\n"
|
||||
"client.debug=false\n"
|
||||
"\n");
|
||||
// These can be set in the environment as well.
|
||||
// e.g. QT_LOGGING_RULES="*.debug=false;qml.debug=true"
|
||||
@ -423,7 +425,8 @@ MainApplication::initQmlLayer()
|
||||
&screenInfo_,
|
||||
this);
|
||||
|
||||
QUrl url;
|
||||
QUrl url = u"qrc:/MainApplicationWindow.qml"_qs;
|
||||
#ifdef QT_DEBUG
|
||||
if (parser_.isSet("test")) {
|
||||
// List the QML files in the project source tree.
|
||||
const auto targetTestComponent = findResource(parser_.value("test"));
|
||||
@ -437,9 +440,8 @@ MainApplication::initQmlLayer()
|
||||
engine_->rootContext()->setContextProperty("testWidth", testWidth);
|
||||
engine_->rootContext()->setContextProperty("testHeight", testHeight);
|
||||
url = u"qrc:/ComponentTestWindow.qml"_qs;
|
||||
} else {
|
||||
url = u"qrc:/MainApplicationWindow.qml"_qs;
|
||||
}
|
||||
#endif
|
||||
QObject::connect(
|
||||
engine_.get(),
|
||||
&QQmlApplicationEngine::objectCreationFailed,
|
||||
@ -449,7 +451,7 @@ MainApplication::initQmlLayer()
|
||||
engine_->load(url);
|
||||
|
||||
// Report the render interface used.
|
||||
C_DBG << "Main window loaded using" << getRenderInterfaceString();
|
||||
C_INFO << "Main window loaded using" << getRenderInterfaceString();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -48,10 +48,10 @@ ListSelectionView {
|
||||
leftPaneItem: viewCoordinator.getView("SidePanel", true)
|
||||
|
||||
rightPaneItem: StackLayout {
|
||||
id: conversationStackLayout
|
||||
objectName: "ConversationLayout"
|
||||
|
||||
currentIndex: !CurrentConversation.hasCall ? 0 : 1
|
||||
onCurrentIndexChanged: chatView.parent = currentIndex === 1 ? callStackView.chatViewContainer : chatViewContainer
|
||||
currentIndex: CurrentConversation.hasCall ? 1 : 0
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
@ -64,24 +64,35 @@ ListSelectionView {
|
||||
ChatView {
|
||||
id: chatView
|
||||
anchors.fill: parent
|
||||
inCallView: parent == callStackView.chatViewContainer
|
||||
|
||||
// Use callStackView.chatViewContainer only when hasCall is true
|
||||
// and callStackView.chatViewContainer not null.
|
||||
// Because after a swarm call ends, callStackView.chatViewContainer might not be null
|
||||
// due to a lack of call state change signals for the swarm call.
|
||||
readonly property bool hasCall: CurrentConversation.hasCall
|
||||
readonly property var inCallChatContainer: hasCall ? callStackView.chatViewContainer : null
|
||||
|
||||
// Parent the chat view to the call stack view when in call.
|
||||
parent: inCallChatContainer ? inCallChatContainer : chatViewContainer
|
||||
inCallView: parent === callStackView.chatViewContainer
|
||||
|
||||
readonly property string currentConvId: CurrentConversation.id
|
||||
onCurrentConvIdChanged: {
|
||||
if (!CurrentConversation.hasCall) {
|
||||
Qt.callLater(focusChatView);
|
||||
} else {
|
||||
dismiss();
|
||||
callStackView.contentView.forceActiveFocus();
|
||||
}
|
||||
Qt.callLater(function() {
|
||||
if (CurrentConversation.hasCall) {
|
||||
callStackView.contentView.forceActiveFocus();
|
||||
} else {
|
||||
focusChatView();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onDismiss: {
|
||||
if (!inCallView) {
|
||||
viewNode.dismiss();
|
||||
} else {
|
||||
if (inCallView) {
|
||||
callStackView.chatViewContainer.visible = false;
|
||||
callStackView.contentView.forceActiveFocus();
|
||||
} else {
|
||||
viewNode.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -112,6 +112,7 @@ Control {
|
||||
},
|
||||
Action {
|
||||
id: shareMenuAction
|
||||
enabled: !CurrentCall.isSharing
|
||||
text: JamiStrings.selectShareMethod
|
||||
property int popupMode: CallActionBar.ActionPopupMode.ListElement
|
||||
property var listModel: ListModel {
|
||||
@ -123,7 +124,7 @@ Control {
|
||||
"Name": JamiStrings.shareScreen,
|
||||
"IconSource": JamiResources.laptop_black_24dp_svg
|
||||
});
|
||||
if (Qt.platform.os.toString() !== "osx" && !UtilsAdapter.isWayland()) {
|
||||
if (Qt.platform.os.toString() !== "osx") {
|
||||
shareModel.append({
|
||||
"Name": JamiStrings.shareWindow,
|
||||
"IconSource": JamiResources.window_black_24dp_svg
|
||||
@ -293,11 +294,28 @@ Control {
|
||||
},
|
||||
Action {
|
||||
id: muteVideoAction
|
||||
onTriggered: CallAdapter.muteCameraToggle()
|
||||
onTriggered: {
|
||||
if (CurrentCall.isSharing && UtilsAdapter.isWayland()) {
|
||||
// Unmuting the camera while a screen share is ongoing causes the daemon
|
||||
// to stop sharing. However, on Wayland, every share has an associated
|
||||
// ScreenCastPortal object which is managed by the client and needs to
|
||||
// be destroyed when the share ends. This is why we explicitly call the
|
||||
// stopSharing function below.
|
||||
//
|
||||
// The muteCamera variable is set whenever a share starts and is normally used
|
||||
// by the stopSharing function to restore the camera to its previous state
|
||||
// when a share ends. Here we know that the user wants to unmute the camera,
|
||||
// so we have to explicitly set muteCamera to false.
|
||||
AvAdapter.muteCamera = false;
|
||||
AvAdapter.stopSharing(CurrentCall.sharingSource);
|
||||
} else {
|
||||
CallAdapter.muteCameraToggle();
|
||||
}
|
||||
}
|
||||
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
|
||||
@ -321,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)
|
||||
},
|
||||
@ -419,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)
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user