Merge pull request #130 from Nheko-Reborn/0.7.0-dev
0.7.0 dev merge to mastermember1-and-too-many-others
@ -0,0 +1,15 @@ |
||||
# |
||||
# Find the lmdb library & include dir. |
||||
# |
||||
|
||||
find_path (LMDB_INCLUDE_DIR NAMES lmdb.h PATHS "$ENV{LMDB_DIR}/include") |
||||
find_library (LMDB_LIBRARY NAMES lmdb PATHS "$ENV{LMDB_DIR}/lib" ) |
||||
include(FindPackageHandleStandardArgs) |
||||
find_package_handle_standard_args(LMDB DEFAULT_MSG LMDB_INCLUDE_DIR LMDB_LIBRARY) |
||||
|
||||
|
||||
add_library(lmdb INTERFACE IMPORTED GLOBAL) |
||||
target_include_directories(lmdb INTERFACE ${LMDB_INCLUDE_DIR}) |
||||
target_link_libraries(lmdb INTERFACE ${LMDB_LIBRARY}) |
||||
|
||||
add_library(liblmdb::lmdb ALIAS lmdb) |
@ -1,44 +0,0 @@ |
||||
# |
||||
# CMake module to search for the olm library |
||||
# |
||||
# On success, the macro sets the following variables: |
||||
# OLM_FOUND = if the library found |
||||
# OLM_LIBRARY = full path to the library |
||||
# OLM_INCLUDE_DIR = where to find the library headers |
||||
# |
||||
if(WIN32) |
||||
message(STATUS "FindOlm is not supported in Windows") |
||||
return() |
||||
endif() |
||||
|
||||
find_path(OLM_INCLUDE_DIR |
||||
NAMES olm/olm.h |
||||
PATHS /usr/include |
||||
/usr/local/include |
||||
$ENV{LIB_DIR}/include |
||||
$ENV{LIB_DIR}/include/olm) |
||||
|
||||
find_library(OLM_LIBRARY |
||||
NAMES olm |
||||
PATHS /usr/lib /usr/local/lib $ENV{LIB_DIR}/lib) |
||||
|
||||
if(OLM_FOUND) |
||||
set(OLM_INCLUDE_DIRS ${OLM_INCLUDE_DIR}) |
||||
|
||||
if(NOT OLM_LIBRARIES) |
||||
set(OLM_LIBRARIES ${OLM_LIBRARY}) |
||||
endif() |
||||
endif() |
||||
|
||||
if(NOT TARGET Olm::Olm) |
||||
add_library(Olm::Olm UNKNOWN IMPORTED) |
||||
set_target_properties(Olm::Olm |
||||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES |
||||
${OLM_INCLUDE_DIR}) |
||||
set_property(TARGET Olm::Olm APPEND PROPERTY IMPORTED_LOCATION ${OLM_LIBRARY}) |
||||
endif() |
||||
|
||||
include(FindPackageHandleStandardArgs) |
||||
find_package_handle_standard_args(OLM DEFAULT_MSG OLM_INCLUDE_DIR OLM_LIBRARY) |
||||
|
||||
mark_as_advanced(OLM_LIBRARY OLM_INCLUDE_DIR) |
@ -0,0 +1,5 @@ |
||||
hunter_config( |
||||
Boost |
||||
VERSION "1.70.0-p0" |
||||
CMAKE_ARGS IOSTREAMS_NO_BZIP2=1 |
||||
) |
@ -0,0 +1,528 @@ |
||||
# Copyright (c) 2013-2019, Ruslan Baratov |
||||
# All rights reserved. |
||||
# |
||||
# Redistribution and use in source and binary forms, with or without |
||||
# modification, are permitted provided that the following conditions are met: |
||||
# |
||||
# * Redistributions of source code must retain the above copyright notice, this |
||||
# list of conditions and the following disclaimer. |
||||
# |
||||
# * Redistributions in binary form must reproduce the above copyright notice, |
||||
# this list of conditions and the following disclaimer in the documentation |
||||
# and/or other materials provided with the distribution. |
||||
# |
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
||||
# This is a gate file to Hunter package manager. |
||||
# Include this file using `include` command and add package you need, example: |
||||
# |
||||
# cmake_minimum_required(VERSION 3.2) |
||||
# |
||||
# include("cmake/HunterGate.cmake") |
||||
# HunterGate( |
||||
# URL "https://github.com/path/to/hunter/archive.tar.gz" |
||||
# SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d" |
||||
# ) |
||||
# |
||||
# project(MyProject) |
||||
# |
||||
# hunter_add_package(Foo) |
||||
# hunter_add_package(Boo COMPONENTS Bar Baz) |
||||
# |
||||
# Projects: |
||||
# * https://github.com/hunter-packages/gate/ |
||||
# * https://github.com/ruslo/hunter |
||||
|
||||
option(HUNTER_ENABLED "Enable Hunter package manager support" ON) |
||||
|
||||
if(HUNTER_ENABLED) |
||||
if(CMAKE_VERSION VERSION_LESS "3.2") |
||||
message( |
||||
FATAL_ERROR |
||||
"At least CMake version 3.2 required for Hunter dependency management." |
||||
" Update CMake or set HUNTER_ENABLED to OFF." |
||||
) |
||||
endif() |
||||
endif() |
||||
|
||||
include(CMakeParseArguments) # cmake_parse_arguments |
||||
|
||||
option(HUNTER_STATUS_PRINT "Print working status" ON) |
||||
option(HUNTER_STATUS_DEBUG "Print a lot info" OFF) |
||||
option(HUNTER_TLS_VERIFY "Enable/disable TLS certificate checking on downloads" ON) |
||||
|
||||
set(HUNTER_ERROR_PAGE "https://docs.hunter.sh/en/latest/reference/errors") |
||||
|
||||
function(hunter_gate_status_print) |
||||
if(HUNTER_STATUS_PRINT OR HUNTER_STATUS_DEBUG) |
||||
foreach(print_message ${ARGV}) |
||||
message(STATUS "[hunter] ${print_message}") |
||||
endforeach() |
||||
endif() |
||||
endfunction() |
||||
|
||||
function(hunter_gate_status_debug) |
||||
if(HUNTER_STATUS_DEBUG) |
||||
foreach(print_message ${ARGV}) |
||||
string(TIMESTAMP timestamp) |
||||
message(STATUS "[hunter *** DEBUG *** ${timestamp}] ${print_message}") |
||||
endforeach() |
||||
endif() |
||||
endfunction() |
||||
|
||||
function(hunter_gate_error_page error_page) |
||||
message("------------------------------ ERROR ------------------------------") |
||||
message(" ${HUNTER_ERROR_PAGE}/${error_page}.html") |
||||
message("-------------------------------------------------------------------") |
||||
message("") |
||||
message(FATAL_ERROR "") |
||||
endfunction() |
||||
|
||||
function(hunter_gate_internal_error) |
||||
message("") |
||||
foreach(print_message ${ARGV}) |
||||
message("[hunter ** INTERNAL **] ${print_message}") |
||||
endforeach() |
||||
message("[hunter ** INTERNAL **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") |
||||
message("") |
||||
hunter_gate_error_page("error.internal") |
||||
endfunction() |
||||
|
||||
function(hunter_gate_fatal_error) |
||||
cmake_parse_arguments(hunter "" "ERROR_PAGE" "" "${ARGV}") |
||||
if("${hunter_ERROR_PAGE}" STREQUAL "") |
||||
hunter_gate_internal_error("Expected ERROR_PAGE") |
||||
endif() |
||||
message("") |
||||
foreach(x ${hunter_UNPARSED_ARGUMENTS}) |
||||
message("[hunter ** FATAL ERROR **] ${x}") |
||||
endforeach() |
||||
message("[hunter ** FATAL ERROR **] [Directory:${CMAKE_CURRENT_LIST_DIR}]") |
||||
message("") |
||||
hunter_gate_error_page("${hunter_ERROR_PAGE}") |
||||
endfunction() |
||||
|
||||
function(hunter_gate_user_error) |
||||
hunter_gate_fatal_error(${ARGV} ERROR_PAGE "error.incorrect.input.data") |
||||
endfunction() |
||||
|
||||
function(hunter_gate_self root version sha1 result) |
||||
string(COMPARE EQUAL "${root}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("root is empty") |
||||
endif() |
||||
|
||||
string(COMPARE EQUAL "${version}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("version is empty") |
||||
endif() |
||||
|
||||
string(COMPARE EQUAL "${sha1}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("sha1 is empty") |
||||
endif() |
||||
|
||||
string(SUBSTRING "${sha1}" 0 7 archive_id) |
||||
|
||||
set( |
||||
hunter_self |
||||
"${root}/_Base/Download/Hunter/${version}/${archive_id}/Unpacked" |
||||
) |
||||
|
||||
set("${result}" "${hunter_self}" PARENT_SCOPE) |
||||
endfunction() |
||||
|
||||
# Set HUNTER_GATE_ROOT cmake variable to suitable value. |
||||
function(hunter_gate_detect_root) |
||||
# Check CMake variable |
||||
string(COMPARE NOTEQUAL "${HUNTER_ROOT}" "" not_empty) |
||||
if(not_empty) |
||||
set(HUNTER_GATE_ROOT "${HUNTER_ROOT}" PARENT_SCOPE) |
||||
hunter_gate_status_debug("HUNTER_ROOT detected by cmake variable") |
||||
return() |
||||
endif() |
||||
|
||||
# Check environment variable |
||||
string(COMPARE NOTEQUAL "$ENV{HUNTER_ROOT}" "" not_empty) |
||||
if(not_empty) |
||||
set(HUNTER_GATE_ROOT "$ENV{HUNTER_ROOT}" PARENT_SCOPE) |
||||
hunter_gate_status_debug("HUNTER_ROOT detected by environment variable") |
||||
return() |
||||
endif() |
||||
|
||||
# Check HOME environment variable |
||||
string(COMPARE NOTEQUAL "$ENV{HOME}" "" result) |
||||
if(result) |
||||
set(HUNTER_GATE_ROOT "$ENV{HOME}/.hunter" PARENT_SCOPE) |
||||
hunter_gate_status_debug("HUNTER_ROOT set using HOME environment variable") |
||||
return() |
||||
endif() |
||||
|
||||
# Check SYSTEMDRIVE and USERPROFILE environment variable (windows only) |
||||
if(WIN32) |
||||
string(COMPARE NOTEQUAL "$ENV{SYSTEMDRIVE}" "" result) |
||||
if(result) |
||||
set(HUNTER_GATE_ROOT "$ENV{SYSTEMDRIVE}/.hunter" PARENT_SCOPE) |
||||
hunter_gate_status_debug( |
||||
"HUNTER_ROOT set using SYSTEMDRIVE environment variable" |
||||
) |
||||
return() |
||||
endif() |
||||
|
||||
string(COMPARE NOTEQUAL "$ENV{USERPROFILE}" "" result) |
||||
if(result) |
||||
set(HUNTER_GATE_ROOT "$ENV{USERPROFILE}/.hunter" PARENT_SCOPE) |
||||
hunter_gate_status_debug( |
||||
"HUNTER_ROOT set using USERPROFILE environment variable" |
||||
) |
||||
return() |
||||
endif() |
||||
endif() |
||||
|
||||
hunter_gate_fatal_error( |
||||
"Can't detect HUNTER_ROOT" |
||||
ERROR_PAGE "error.detect.hunter.root" |
||||
) |
||||
endfunction() |
||||
|
||||
function(hunter_gate_download dir) |
||||
string( |
||||
COMPARE |
||||
NOTEQUAL |
||||
"$ENV{HUNTER_DISABLE_AUTOINSTALL}" |
||||
"" |
||||
disable_autoinstall |
||||
) |
||||
if(disable_autoinstall AND NOT HUNTER_RUN_INSTALL) |
||||
hunter_gate_fatal_error( |
||||
"Hunter not found in '${dir}'" |
||||
"Set HUNTER_RUN_INSTALL=ON to auto-install it from '${HUNTER_GATE_URL}'" |
||||
"Settings:" |
||||
" HUNTER_ROOT: ${HUNTER_GATE_ROOT}" |
||||
" HUNTER_SHA1: ${HUNTER_GATE_SHA1}" |
||||
ERROR_PAGE "error.run.install" |
||||
) |
||||
endif() |
||||
string(COMPARE EQUAL "${dir}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("Empty 'dir' argument") |
||||
endif() |
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("HUNTER_GATE_SHA1 empty") |
||||
endif() |
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" is_bad) |
||||
if(is_bad) |
||||
hunter_gate_internal_error("HUNTER_GATE_URL empty") |
||||
endif() |
||||
|
||||
set(done_location "${dir}/DONE") |
||||
set(sha1_location "${dir}/SHA1") |
||||
|
||||
set(build_dir "${dir}/Build") |
||||
set(cmakelists "${dir}/CMakeLists.txt") |
||||
|
||||
hunter_gate_status_debug("Locking directory: ${dir}") |
||||
file(LOCK "${dir}" DIRECTORY GUARD FUNCTION) |
||||
hunter_gate_status_debug("Lock done") |
||||
|
||||
if(EXISTS "${done_location}") |
||||
# while waiting for lock other instance can do all the job |
||||
hunter_gate_status_debug("File '${done_location}' found, skip install") |
||||
return() |
||||
endif() |
||||
|
||||
file(REMOVE_RECURSE "${build_dir}") |
||||
file(REMOVE_RECURSE "${cmakelists}") |
||||
|
||||
file(MAKE_DIRECTORY "${build_dir}") # check directory permissions |
||||
|
||||
# Disabling languages speeds up a little bit, reduces noise in the output |
||||
# and avoids path too long windows error |
||||
file( |
||||
WRITE |
||||
"${cmakelists}" |
||||
"cmake_minimum_required(VERSION 3.2)\n" |
||||
"project(HunterDownload LANGUAGES NONE)\n" |
||||
"include(ExternalProject)\n" |
||||
"ExternalProject_Add(\n" |
||||
" Hunter\n" |
||||
" URL\n" |
||||
" \"${HUNTER_GATE_URL}\"\n" |
||||
" URL_HASH\n" |
||||
" SHA1=${HUNTER_GATE_SHA1}\n" |
||||
" DOWNLOAD_DIR\n" |
||||
" \"${dir}\"\n" |
||||
" TLS_VERIFY\n" |
||||
" ${HUNTER_TLS_VERIFY}\n" |
||||
" SOURCE_DIR\n" |
||||
" \"${dir}/Unpacked\"\n" |
||||
" CONFIGURE_COMMAND\n" |
||||
" \"\"\n" |
||||
" BUILD_COMMAND\n" |
||||
" \"\"\n" |
||||
" INSTALL_COMMAND\n" |
||||
" \"\"\n" |
||||
")\n" |
||||
) |
||||
|
||||
if(HUNTER_STATUS_DEBUG) |
||||
set(logging_params "") |
||||
else() |
||||
set(logging_params OUTPUT_QUIET) |
||||
endif() |
||||
|
||||
hunter_gate_status_debug("Run generate") |
||||
|
||||
# Need to add toolchain file too. |
||||
# Otherwise on Visual Studio + MDD this will fail with error: |
||||
# "Could not find an appropriate version of the Windows 10 SDK installed on this machine" |
||||
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}") |
||||
get_filename_component(absolute_CMAKE_TOOLCHAIN_FILE "${CMAKE_TOOLCHAIN_FILE}" ABSOLUTE) |
||||
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=${absolute_CMAKE_TOOLCHAIN_FILE}") |
||||
else() |
||||
# 'toolchain_arg' can't be empty |
||||
set(toolchain_arg "-DCMAKE_TOOLCHAIN_FILE=") |
||||
endif() |
||||
|
||||
string(COMPARE EQUAL "${CMAKE_MAKE_PROGRAM}" "" no_make) |
||||
if(no_make) |
||||
set(make_arg "") |
||||
else() |
||||
# Test case: remove Ninja from PATH but set it via CMAKE_MAKE_PROGRAM |
||||
set(make_arg "-DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM}") |
||||
endif() |
||||
|
||||
execute_process( |
||||
COMMAND |
||||
"${CMAKE_COMMAND}" |
||||
"-H${dir}" |
||||
"-B${build_dir}" |
||||
"-G${CMAKE_GENERATOR}" |
||||
"${toolchain_arg}" |
||||
${make_arg} |
||||
WORKING_DIRECTORY "${dir}" |
||||
RESULT_VARIABLE download_result |
||||
${logging_params} |
||||
) |
||||
|
||||
if(NOT download_result EQUAL 0) |
||||
hunter_gate_internal_error( |
||||
"Configure project failed." |
||||
"To reproduce the error run: ${CMAKE_COMMAND} -H${dir} -B${build_dir} -G${CMAKE_GENERATOR} ${toolchain_arg} ${make_arg}" |
||||
"In directory ${dir}" |
||||
) |
||||
endif() |
||||
|
||||
hunter_gate_status_print( |
||||
"Initializing Hunter workspace (${HUNTER_GATE_SHA1})" |
||||
" ${HUNTER_GATE_URL}" |
||||
" -> ${dir}" |
||||
) |
||||
execute_process( |
||||
COMMAND "${CMAKE_COMMAND}" --build "${build_dir}" |
||||
WORKING_DIRECTORY "${dir}" |
||||
RESULT_VARIABLE download_result |
||||
${logging_params} |
||||
) |
||||
|
||||
if(NOT download_result EQUAL 0) |
||||
hunter_gate_internal_error("Build project failed") |
||||
endif() |
||||
|
||||
file(REMOVE_RECURSE "${build_dir}") |
||||
file(REMOVE_RECURSE "${cmakelists}") |
||||
|
||||
file(WRITE "${sha1_location}" "${HUNTER_GATE_SHA1}") |
||||
file(WRITE "${done_location}" "DONE") |
||||
|
||||
hunter_gate_status_debug("Finished") |
||||
endfunction() |
||||
|
||||
# Must be a macro so master file 'cmake/Hunter' can |
||||
# apply all variables easily just by 'include' command |
||||
# (otherwise PARENT_SCOPE magic needed) |
||||
macro(HunterGate) |
||||
if(HUNTER_GATE_DONE) |
||||
# variable HUNTER_GATE_DONE set explicitly for external project |
||||
# (see `hunter_download`) |
||||
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) |
||||
endif() |
||||
|
||||
# First HunterGate command will init Hunter, others will be ignored |
||||
get_property(_hunter_gate_done GLOBAL PROPERTY HUNTER_GATE_DONE SET) |
||||
|
||||
if(NOT HUNTER_ENABLED) |
||||
# Empty function to avoid error "unknown function" |
||||
function(hunter_add_package) |
||||
endfunction() |
||||
|
||||
set( |
||||
_hunter_gate_disabled_mode_dir |
||||
"${CMAKE_CURRENT_LIST_DIR}/cmake/Hunter/disabled-mode" |
||||
) |
||||
if(EXISTS "${_hunter_gate_disabled_mode_dir}") |
||||
hunter_gate_status_debug( |
||||
"Adding \"disabled-mode\" modules: ${_hunter_gate_disabled_mode_dir}" |
||||
) |
||||
list(APPEND CMAKE_PREFIX_PATH "${_hunter_gate_disabled_mode_dir}") |
||||
endif() |
||||
elseif(_hunter_gate_done) |
||||
hunter_gate_status_debug("Secondary HunterGate (use old settings)") |
||||
hunter_gate_self( |
||||
"${HUNTER_CACHED_ROOT}" |
||||
"${HUNTER_VERSION}" |
||||
"${HUNTER_SHA1}" |
||||
_hunter_self |
||||
) |
||||
include("${_hunter_self}/cmake/Hunter") |
||||
else() |
||||
set(HUNTER_GATE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}") |
||||
|
||||
string(COMPARE NOTEQUAL "${PROJECT_NAME}" "" _have_project_name) |
||||
if(_have_project_name) |
||||
hunter_gate_fatal_error( |
||||
"Please set HunterGate *before* 'project' command. " |
||||
"Detected project: ${PROJECT_NAME}" |
||||
ERROR_PAGE "error.huntergate.before.project" |
||||
) |
||||
endif() |
||||
|
||||
cmake_parse_arguments( |
||||
HUNTER_GATE "LOCAL" "URL;SHA1;GLOBAL;FILEPATH" "" ${ARGV} |
||||
) |
||||
|
||||
string(COMPARE EQUAL "${HUNTER_GATE_SHA1}" "" _empty_sha1) |
||||
string(COMPARE EQUAL "${HUNTER_GATE_URL}" "" _empty_url) |
||||
string( |
||||
COMPARE |
||||
NOTEQUAL |
||||
"${HUNTER_GATE_UNPARSED_ARGUMENTS}" |
||||
"" |
||||
_have_unparsed |
||||
) |
||||
string(COMPARE NOTEQUAL "${HUNTER_GATE_GLOBAL}" "" _have_global) |
||||
string(COMPARE NOTEQUAL "${HUNTER_GATE_FILEPATH}" "" _have_filepath) |
||||
|
||||
if(_have_unparsed) |
||||
hunter_gate_user_error( |
||||
"HunterGate unparsed arguments: ${HUNTER_GATE_UNPARSED_ARGUMENTS}" |
||||
) |
||||
endif() |
||||
if(_empty_sha1) |
||||
hunter_gate_user_error("SHA1 suboption of HunterGate is mandatory") |
||||
endif() |
||||
if(_empty_url) |
||||
hunter_gate_user_error("URL suboption of HunterGate is mandatory") |
||||
endif() |
||||
if(_have_global) |
||||
if(HUNTER_GATE_LOCAL) |
||||
hunter_gate_user_error("Unexpected LOCAL (already has GLOBAL)") |
||||
endif() |
||||
if(_have_filepath) |
||||
hunter_gate_user_error("Unexpected FILEPATH (already has GLOBAL)") |
||||
endif() |
||||
endif() |
||||
if(HUNTER_GATE_LOCAL) |
||||
if(_have_global) |
||||
hunter_gate_user_error("Unexpected GLOBAL (already has LOCAL)") |
||||
endif() |
||||
if(_have_filepath) |
||||
hunter_gate_user_error("Unexpected FILEPATH (already has LOCAL)") |
||||
endif() |
||||
endif() |
||||
if(_have_filepath) |
||||
if(_have_global) |
||||
hunter_gate_user_error("Unexpected GLOBAL (already has FILEPATH)") |
||||
endif() |
||||
if(HUNTER_GATE_LOCAL) |
||||
hunter_gate_user_error("Unexpected LOCAL (already has FILEPATH)") |
||||
endif() |
||||
endif() |
||||
|
||||
hunter_gate_detect_root() # set HUNTER_GATE_ROOT |
||||
|
||||
# Beautify path, fix probable problems with windows path slashes |
||||
get_filename_component( |
||||
HUNTER_GATE_ROOT "${HUNTER_GATE_ROOT}" ABSOLUTE |
||||
) |
||||
hunter_gate_status_debug("HUNTER_ROOT: ${HUNTER_GATE_ROOT}") |
||||
if(NOT HUNTER_ALLOW_SPACES_IN_PATH) |
||||
string(FIND "${HUNTER_GATE_ROOT}" " " _contain_spaces) |
||||
if(NOT _contain_spaces EQUAL -1) |
||||
hunter_gate_fatal_error( |
||||
"HUNTER_ROOT (${HUNTER_GATE_ROOT}) contains spaces." |
||||
"Set HUNTER_ALLOW_SPACES_IN_PATH=ON to skip this error" |
||||
"(Use at your own risk!)" |
||||
ERROR_PAGE "error.spaces.in.hunter.root" |
||||
) |
||||
endif() |
||||
endif() |
||||
|
||||
string( |
||||
REGEX |
||||
MATCH |
||||
"[0-9]+\\.[0-9]+\\.[0-9]+[-_a-z0-9]*" |
||||
HUNTER_GATE_VERSION |
||||
"${HUNTER_GATE_URL}" |
||||
) |
||||
string(COMPARE EQUAL "${HUNTER_GATE_VERSION}" "" _is_empty) |
||||
if(_is_empty) |
||||
set(HUNTER_GATE_VERSION "unknown") |
||||
endif() |
||||
|
||||
hunter_gate_self( |
||||
"${HUNTER_GATE_ROOT}" |
||||
"${HUNTER_GATE_VERSION}" |
||||
"${HUNTER_GATE_SHA1}" |
||||
_hunter_self |
||||
) |
||||
|
||||
set(_master_location "${_hunter_self}/cmake/Hunter") |
||||
get_filename_component(_archive_id_location "${_hunter_self}/.." ABSOLUTE) |
||||
set(_done_location "${_archive_id_location}/DONE") |
||||
set(_sha1_location "${_archive_id_location}/SHA1") |
||||
|
||||
# Check Hunter already downloaded by HunterGate |
||||
if(NOT EXISTS "${_done_location}") |
||||
hunter_gate_download("${_archive_id_location}") |
||||
endif() |
||||
|
||||
if(NOT EXISTS "${_done_location}") |
||||
hunter_gate_internal_error("hunter_gate_download failed") |
||||
endif() |
||||
|
||||
if(NOT EXISTS "${_sha1_location}") |
||||
hunter_gate_internal_error("${_sha1_location} not found") |
||||
endif() |
||||
file(READ "${_sha1_location}" _sha1_value) |
||||
string(COMPARE EQUAL "${_sha1_value}" "${HUNTER_GATE_SHA1}" _is_equal) |
||||
if(NOT _is_equal) |
||||
hunter_gate_internal_error( |
||||
"Short SHA1 collision:" |
||||
" ${_sha1_value} (from ${_sha1_location})" |
||||
" ${HUNTER_GATE_SHA1} (HunterGate)" |
||||
) |
||||
endif() |
||||
if(NOT EXISTS "${_master_location}") |
||||
hunter_gate_user_error( |
||||
"Master file not found:" |
||||
" ${_master_location}" |
||||
"try to update Hunter/HunterGate" |
||||
) |
||||
endif() |
||||
include("${_master_location}") |
||||
set_property(GLOBAL PROPERTY HUNTER_GATE_DONE YES) |
||||
endif() |
||||
endmacro() |
@ -1,29 +0,0 @@ |
||||
# |
||||
# Find the lmdb library & include dir. |
||||
# Build lmdb on Appveyor. |
||||
# |
||||
|
||||
if(APPVEYOR_BUILD) |
||||
set(LMDB_VERSION "LMDB_0.9.21") |
||||
set(NTDLIB "C:/WINDDK/7600.16385.1/lib/win7/amd64/ntdll.lib") |
||||
|
||||
execute_process( |
||||
COMMAND git clone --depth=1 --branch ${LMDB_VERSION} https://github.com/LMDB/lmdb) |
||||
|
||||
set(LMDB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/lmdb/libraries/liblmdb) |
||||
|
||||
add_library(lmdb |
||||
${CMAKE_SOURCE_DIR}/lmdb/libraries/liblmdb/lmdb.h |
||||
${CMAKE_SOURCE_DIR}/lmdb/libraries/liblmdb/mdb.c |
||||
${CMAKE_SOURCE_DIR}/lmdb/libraries/liblmdb/midl.h |
||||
${CMAKE_SOURCE_DIR}/lmdb/libraries/liblmdb/midl.c) |
||||
|
||||
set(LMDB_LIBRARY lmdb) |
||||
else() |
||||
find_path (LMDB_INCLUDE_DIR NAMES lmdb.h PATHS "$ENV{LMDB_DIR}/include") |
||||
find_library (LMDB_LIBRARY NAMES lmdb PATHS "$ENV{LMDB_DIR}/lib" ) |
||||
include(FindPackageHandleStandardArgs) |
||||
find_package_handle_standard_args(LMDB DEFAULT_MSG LMDB_INCLUDE_DIR LMDB_LIBRARY) |
||||
endif() |
||||
|
||||
include_directories(${LMDB_INCLUDE_DIR}) |
@ -1,125 +0,0 @@ |
||||
cmake_minimum_required(VERSION 3.11) |
||||
project(NHEKO_DEPS) |
||||
|
||||
# Point CMake at any custom modules we may ship |
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") |
||||
|
||||
if(NOT CMAKE_BUILD_TYPE) |
||||
set(CMAKE_BUILD_TYPE Release) |
||||
endif() |
||||
|
||||
set(DEPS_INSTALL_DIR "${CMAKE_BINARY_DIR}/usr" |
||||
CACHE PATH "Dependencies install directory.") |
||||
set(DEPS_BIN_DIR "${DEPS_INSTALL_DIR}/bin" |
||||
CACHE PATH "Dependencies binary install directory.") |
||||
set(DEPS_LIB_DIR "${DEPS_INSTALL_DIR}/lib" |
||||
CACHE PATH "Dependencies library install directory.") |
||||
set(DEPS_BUILD_DIR "${CMAKE_BINARY_DIR}/build" |
||||
CACHE PATH "Dependencies build directory.") |
||||
set(DEPS_DOWNLOAD_DIR "${DEPS_BUILD_DIR}/downloads" |
||||
CACHE PATH "Dependencies download directory.") |
||||
|
||||
option(USE_BUNDLED "Use bundled dependencies." ON) |
||||
|
||||
option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_CMARK "Use the bundled version of cmark." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_OLM "Use the bundled version of libolm." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_TWEENY "Use the bundled version of Tweeny." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdbxx." ${USE_BUNDLED}) |
||||
option(USE_BUNDLED_MATRIX_CLIENT "Use the bundled version of mtxclient." |
||||
${USE_BUNDLED}) |
||||
option(USE_BUNDLED_JSON "Use the bundled version of nlohmann json." ${USE_BUNDLED}) |
||||
option(MTX_STATIC "Compile / link bundled mtx client statically" OFF) |
||||
|
||||
if(USE_BUNDLED_BOOST) |
||||
# bundled boost is 1.68, which requires CMake 3.12 or greater. |
||||
cmake_minimum_required(VERSION 3.12) |
||||
endif() |
||||
|
||||
include(ExternalProject) |
||||
|
||||
set(BOOST_URL |
||||
https://dl.bintray.com/boostorg/release/1.69.0/source/boost_1_69_0.tar.bz2) |
||||
set(BOOST_SHA256 |
||||
8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406) |
||||
|
||||
set( |
||||
MTXCLIENT_URL |
||||
https://github.com/Nheko-Reborn/mtxclient/archive/975ce8906c42742dbb698fcf9fa15663c530df20.tar.gz) |
||||
set(MTXCLIENT_HASH |
||||
5e3169ef19b6e585069ceced42489574ce18380480628339bac015759fa1893e) |
||||
set( |
||||
TWEENY_URL |
||||
https://github.com/mobius3/tweeny/archive/b94ce07cfb02a0eb8ac8aaf66137dabdaea857cf.tar.gz |
||||
) |
||||
set(TWEENY_HASH |
||||
9a632b9da84823fae002ad5d9ba02c8d77c0a3810479974c6b637c5504165475) |
||||
|
||||
set( |
||||
LMDBXX_HEADER_URL |
||||
https://raw.githubusercontent.com/bendiken/lmdbxx/0b43ca87d8cfabba392dfe884eb1edb83874de02/lmdb%2B%2B.h |
||||
) |
||||
set(LMDBXX_HASH |
||||
c57b501a4e8fa1187fa7fd348da415c7685a50a7cb25b17b3f257b9e9426f73d) |
||||
|
||||
set(OLM_URL https://gitlab.matrix.org/matrix-org/olm.git) |
||||
set(OLM_TAG 4065c8e11a33ba41133a086ed3de4da94dcb6bae) |
||||
|
||||
set(CMARK_URL https://github.com/commonmark/cmark/archive/0.28.3.tar.gz) |
||||
set(CMARK_HASH acc98685d3c1b515ff787ac7c994188dadaf28a2d700c10c1221da4199bae1fc) |
||||
|
||||
set(SPDLOG_URL https://github.com/gabime/spdlog/archive/v1.1.0.tar.gz) |
||||
set(SPDLOG_HASH |
||||
3dbcbfd8c07e25f5e0d662b194d3a7772ef214358c49ada23c044c4747ce8b19) |
||||
|
||||
set(JSON_URL |
||||
https://github.com/nlohmann/json.git) |
||||
set(JSON_TAG |
||||
v3.2.0) |
||||
|
||||
if(USE_BUNDLED_JSON) |
||||
include(Json) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_BOOST) |
||||
include(Boost) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_SPDLOG) |
||||
include(SpdLog) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_OLM) |
||||
include(Olm) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_CMARK) |
||||
include(cmark) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_TWEENY) |
||||
include(Tweeny) |
||||
endif() |
||||
|
||||
if(USE_BUNDLED_LMDBXX) |
||||
file(DOWNLOAD ${LMDBXX_HEADER_URL} ${DEPS_INSTALL_DIR}/include/lmdb++.h |
||||
EXPECTED_HASH SHA256=${LMDBXX_HASH}) |
||||
endif() |
||||
|
||||
if(WIN32) |
||||
if("${TARGET_ARCH}" STREQUAL "X86_64") |
||||
set(TARGET_ARCH x64) |
||||
elseif(TARGET_ARCH STREQUAL "X86") |
||||
set(TARGET_ARCH ia32) |
||||
endif() |
||||
endif() |
||||
|
||||
add_custom_target(third-party ALL |
||||
COMMAND ${CMAKE_COMMAND} -E touch .third-party |
||||
DEPENDS ${THIRD_PARTY_DEPS}) |
||||
|
||||
if(USE_BUNDLED_MATRIX_CLIENT) |
||||
include(MatrixClient) |
||||
add_dependencies(MatrixClient third-party) |
||||
endif() |
@ -1,23 +0,0 @@ |
||||
if(WIN32) |
||||
message(STATUS "Building Boost in Windows is not supported (skipping)") |
||||
return() |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
Boost |
||||
|
||||
URL ${BOOST_URL} |
||||
URL_HASH SHA256=${BOOST_SHA256} |
||||
DOWNLOAD_DIR ${DEPS_DOWNLOAD_DIR}/boost |
||||
DOWNLOAD_NO_PROGRESS 0 |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/boost |
||||
CONFIGURE_COMMAND ${DEPS_BUILD_DIR}/boost/bootstrap.sh |
||||
--with-libraries=random,thread,system,iostreams,atomic,chrono,date_time,regex |
||||
--prefix=${DEPS_INSTALL_DIR} |
||||
BUILD_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 cxxstd=14 variant=release link=shared runtime-link=shared threading=multi --layout=system |
||||
INSTALL_COMMAND ${DEPS_BUILD_DIR}/boost/b2 -d0 install |
||||
) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Boost) |
@ -1,19 +0,0 @@ |
||||
ExternalProject_Add( |
||||
Json |
||||
|
||||
GIT_REPOSITORY ${JSON_URL} |
||||
GIT_TAG ${JSON_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/json |
||||
|
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DJSON_BuildTests=OFF |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} |
||||
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR}/json |
||||
INSTALL_COMMAND make install |
||||
) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Json) |
@ -1,43 +0,0 @@ |
||||
set(PLATFORM_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(PLATFORM_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
if(APPLE) |
||||
set(PLATFORM_FLAGS "-DOPENSSL_ROOT_DIR=/usr/local/opt/openssl") |
||||
endif() |
||||
|
||||
# Force to build with the bundled version of Boost. This is necessary because |
||||
# if an outdated version of Boost is installed, then CMake will grab that |
||||
# instead of the bundled version of Boost, like we wanted. |
||||
set(BOOST_BUNDLE_ROOT "-DBOOST_ROOT=${DEPS_BUILD_DIR}/boost") |
||||
|
||||
set (MTX_SHARED ON) |
||||
|
||||
if (MTX_STATIC) |
||||
set (MTX_SHARED OFF) |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
MatrixClient |
||||
|
||||
URL ${MTXCLIENT_URL} |
||||
URL_HASH SHA256=${MTXCLIENT_HASH} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/mtxclient |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_BUILD_TYPE=Release |
||||
-DBUILD_LIB_TESTS=OFF |
||||
-DBUILD_LIB_EXAMPLES=OFF |
||||
-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} |
||||
${BOOST_BUNDLE_ROOT} |
||||
-DBUILD_SHARED_LIBS=${MTX_SHARED} |
||||
${PLATFORM_FLAGS} |
||||
${DEPS_BUILD_DIR}/mtxclient |
||||
BUILD_COMMAND |
||||
${CMAKE_COMMAND} --build ${DEPS_BUILD_DIR}/mtxclient --config Release) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS MatrixClient) |
@ -1,34 +0,0 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
Olm |
||||
|
||||
GIT_REPOSITORY ${OLM_URL} |
||||
GIT_TAG ${OLM_TAG} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/olm |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} -E copy |
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmCMakeLists.txt |
||||
${DEPS_BUILD_DIR}/olm/CMakeLists.txt |
||||
COMMAND ${CMAKE_COMMAND} -E copy |
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/OlmConfig.cmake.in |
||||
${DEPS_BUILD_DIR}/olm/cmake/OlmConfig.cmake.in |
||||
COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMAKE_BUILD_TYPE=Release |
||||
${DEPS_BUILD_DIR}/olm |
||||
${WINDOWS_FLAGS} |
||||
BUILD_COMMAND ${CMAKE_COMMAND} |
||||
--build ${DEPS_BUILD_DIR}/olm |
||||
--config Release |
||||
INSTALL_COMMAND ${CMAKE_COMMAND} |
||||
--build ${DEPS_BUILD_DIR}/olm |
||||
--config Release |
||||
--target install) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Olm) |
@ -1,107 +0,0 @@ |
||||
cmake_minimum_required(VERSION 3.1) |
||||
|
||||
project(olm VERSION 2.2.2 LANGUAGES CXX C) |
||||
|
||||
add_definitions(-DOLMLIB_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}) |
||||
add_definitions(-DOLMLIB_VERSION_MINOR=${PROJECT_VERSION_MINOR}) |
||||
add_definitions(-DOLMLIB_VERSION_PATCH=${PROJECT_VERSION_PATCH}) |
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) |
||||
set(CMAKE_CXX_STANDARD 11) |
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON) |
||||
set(CMAKE_C_STANDARD 99) |
||||
set(CMAKE_C_STANDARD_REQUIRED ON) |
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON) |
||||
|
||||
if(NOT CMAKE_BUILD_TYPE) |
||||
set(CMAKE_BUILD_TYPE Release) |
||||
endif() |
||||
|
||||
add_library(olm |
||||
src/account.cpp |
||||
src/base64.cpp |
||||
src/cipher.cpp |
||||
src/crypto.cpp |
||||
src/memory.cpp |
||||
src/message.cpp |
||||
src/pickle.cpp |
||||
src/ratchet.cpp |
||||
src/session.cpp |
||||
src/utility.cpp |
||||
|
||||
src/ed25519.c |
||||
src/error.c |
||||
src/inbound_group_session.c |
||||
src/megolm.c |
||||
src/olm.cpp |
||||
src/outbound_group_session.c |
||||
src/pickle_encoding.c |
||||
|
||||
lib/crypto-algorithms/aes.c |
||||
lib/crypto-algorithms/sha256.c |
||||
lib/curve25519-donna/curve25519-donna.c) |
||||
add_library(Olm::Olm ALIAS olm) |
||||
|
||||
target_include_directories(olm |
||||
PUBLIC |
||||
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include> |
||||
$<INSTALL_INTERFACE:include> |
||||
PRIVATE |
||||
${CMAKE_CURRENT_SOURCE_DIR}/lib) |
||||
|
||||
set_target_properties(olm PROPERTIES |
||||
SOVERSION ${PROJECT_VERSION_MAJOR} |
||||
VERSION ${PROJECT_VERSION}) |
||||
|
||||
set_target_properties(olm PROPERTIES |
||||
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR} |
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR} |
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) |
||||
|
||||
# |
||||
# Installation |
||||
# |
||||
include(GNUInstallDirs) |
||||
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/Olm) |
||||
install(TARGETS olm |
||||
EXPORT olm-targets |
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} |
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) |
||||
|
||||
# The exported target will be named Olm. |
||||
set_target_properties(olm PROPERTIES EXPORT_NAME Olm) |
||||
install(FILES |
||||
${CMAKE_SOURCE_DIR}/include/olm/olm.h |
||||
${CMAKE_SOURCE_DIR}/include/olm/outbound_group_session.h |
||||
${CMAKE_SOURCE_DIR}/include/olm/inbound_group_session.h |
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/olm) |
||||
|
||||
# Export the targets to a script. |
||||
install(EXPORT olm-targets |
||||
FILE OlmTargets.cmake |
||||
NAMESPACE Olm:: |
||||
DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
# Create a ConfigVersion.cmake file. |
||||
include(CMakePackageConfigHelpers) |
||||
write_basic_package_version_file( |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake |
||||
VERSION ${PROJECT_VERSION} |
||||
COMPATIBILITY SameMajorVersion) |
||||
|
||||
configure_package_config_file( |
||||
${CMAKE_CURRENT_LIST_DIR}/cmake/OlmConfig.cmake.in |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake |
||||
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
#Install the config & configversion. |
||||
install(FILES |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfig.cmake |
||||
${CMAKE_CURRENT_BINARY_DIR}/OlmConfigVersion.cmake |
||||
DESTINATION ${INSTALL_CONFIGDIR}) |
||||
|
||||
# Register package in user's package registry |
||||
export(EXPORT olm-targets |
||||
FILE ${CMAKE_CURRENT_BINARY_DIR}/OlmTargets.cmake |
||||
NAMESPACE Olm::) |
||||
export(PACKAGE Olm) |
@ -1,11 +0,0 @@ |
||||
get_filename_component(Olm_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) |
||||
include(CMakeFindDependencyMacro) |
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${Olm_CMAKE_DIR}) |
||||
list(REMOVE_AT CMAKE_MODULE_PATH -1) |
||||
|
||||
if(NOT TARGET Olm::Olm) |
||||
include("${Olm_CMAKE_DIR}/OlmTargets.cmake") |
||||
endif() |
||||
|
||||
set(Olm_LIBRARIES Olm::Olm) |
@ -1,23 +0,0 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
SpdLog |
||||
|
||||
URL ${SPDLOG_URL} |
||||
URL_HASH SHA256=${SPDLOG_HASH} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/spdlog |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DSPDLOG_BUILD_EXAMPLES=0 |
||||
-DSPDLOG_BUILD_BENCH=0 |
||||
-DSPDLOG_BUILD_TESTING=0 |
||||
${DEPS_BUILD_DIR}/spdlog |
||||
${WINDOWS_FLAGS}) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS SpdLog) |
@ -1,22 +0,0 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
Tweeny |
||||
|
||||
URL ${TWEENY_URL} |
||||
URL_HASH SHA256=${TWEENY_HASH} |
||||
|
||||
BUILD_IN_SOURCE 1 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/tweeny |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DTWEENY_BUILD_EXAMPLES=OFF |
||||
-DTWEENY_BUILD_DOCUMENTATION=OFF |
||||
${DEPS_BUILD_DIR}/tweeny |
||||
${WINDOWS_FLAGS}) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS Tweeny) |
@ -1,21 +0,0 @@ |
||||
set(WINDOWS_FLAGS "") |
||||
|
||||
if(MSVC) |
||||
set(WINDOWS_FLAGS "-DCMAKE_GENERATOR_PLATFORM=x64") |
||||
endif() |
||||
|
||||
ExternalProject_Add( |
||||
cmark |
||||
|
||||
URL ${CMARK_URL} |
||||
URL_HASH SHA256=${CMARK_HASH} |
||||
|
||||
BUILD_IN_SOURCE 0 |
||||
SOURCE_DIR ${DEPS_BUILD_DIR}/cmark |
||||
CONFIGURE_COMMAND ${CMAKE_COMMAND} |
||||
-DCMAKE_INSTALL_PREFIX=${DEPS_INSTALL_DIR} |
||||
-DCMARK_TESTS=OFF |
||||
${DEPS_BUILD_DIR}/cmark |
||||
${WINDOWS_FLAGS}) |
||||
|
||||
list(APPEND THIRD_PARTY_DEPS cmark) |
@ -0,0 +1,194 @@ |
||||
{ |
||||
"id": "io.github.NhekoReborn.Nheko", |
||||
"command": "nheko", |
||||
"branch": "0.7.0-dev", |
||||
"runtime": "org.kde.Platform", |
||||
"runtime-version": "5.14", |
||||
"sdk": "org.kde.Sdk", |
||||
"rename-icon": "nheko", |
||||
"rename-desktop-file": "nheko.desktop", |
||||
"rename-appdata-file": "nheko.appdata.xml", |
||||
"finish-args": [ |
||||
"--device=dri", |
||||
"--filesystem=home", |
||||
"--share=ipc", |
||||
"--share=network", |
||||
"--socket=pulseaudio", |
||||
"--socket=wayland", |
||||
"--socket=x11", |
||||
"--talk-name=org.freedesktop.Notifications", |
||||
"--talk-name=org.kde.StatusNotifierWatcher" |
||||
], |
||||
"cleanup": [ |
||||
"/include", |
||||
"/bin/mdb*", |
||||
"*.a" |
||||
], |
||||
"build-options" : { |
||||
"arch": { |
||||
"aarch64": { |
||||
"cxxflags": "-DBOOST_ASIO_DISABLE_EPOLL" |
||||
} |
||||
} |
||||
}, |
||||
"modules": [ |
||||
{ |
||||
"name": "lmdb", |
||||
"sources": [ |
||||
{ |
||||
"sha256": "f3927859882eb608868c8c31586bb7eb84562a40a6bf5cc3e13b6b564641ea28", |
||||
"type": "archive", |
||||
"url": "https://github.com/LMDB/lmdb/archive/LMDB_0.9.22.tar.gz" |
||||
} |
||||
], |
||||
"make-install-args": [ |
||||
"prefix=/app" |
||||
], |
||||
"no-autogen": true, |
||||
"subdir": "libraries/liblmdb" |
||||
}, |
||||
{ |
||||
"name": "cmark", |
||||
"buildsystem": "cmake-ninja", |
||||
"builddir": true, |
||||
"config-opts": [ |
||||
"-DCMAKE_BUILD_TYPE=Release", |
||||
"-DCMARK_TESTS=OFF" |
||||
], |
||||
"sources": [ |
||||
{ |
||||
"sha256": "2558ace3cbeff85610de3bda32858f722b359acdadf0c4691851865bb84924a6", |
||||
"type": "archive", |
||||
"url": "https://github.com/commonmark/cmark/archive/0.29.0.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "spdlog", |
||||
"buildsystem": "cmake-ninja", |
||||
"config-opts": [ |
||||
"-DCMAKE_BUILD_TYPE=Release", |
||||
"-DSPDLOG_BUILD_EXAMPLES=0", |
||||
"-DSPDLOG_BUILD_BENCH=0", |
||||
"-DSPDLOG_BUILD_TESTING=0" |
||||
], |
||||
"sources": [ |
||||
{ |
||||
"sha256": "3dbcbfd8c07e25f5e0d662b194d3a7772ef214358c49ada23c044c4747ce8b19", |
||||
"type": "archive", |
||||
"url": "https://github.com/gabime/spdlog/archive/v1.1.0.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"config-opts": [ |
||||
"-DCMAKE_BUILD_TYPE=Release" |
||||
], |
||||
"buildsystem": "cmake-ninja", |
||||
"name": "olm", |
||||
"sources": [ |
||||
{ |
||||
"commit": "6753595300767dd70150831dbbe6f92d64e75038", |
||||
"disable-shallow-clone": true, |
||||
"tag": "3.1.4", |
||||
"type": "git", |
||||
"url": "https://gitlab.matrix.org/matrix-org/olm.git" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"config-opts":[ |
||||
"-DJSON_BuildTests=OFF" |
||||
], |
||||
"buildsystem":"cmake", |
||||
"name": "nlohmann", |
||||
"sources":[ |
||||
{ |
||||
"sha256": "d51a3a8d3efbb1139d7608e28782ea9efea7e7933157e8ff8184901efd8ee760", |
||||
"type": "archive", |
||||
"url": "https://github.com/nlohmann/json/archive/v3.7.0.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"name": "sodium", |
||||
"sources": [ |
||||
{ |
||||
"sha256": "6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e46636c1", |
||||
"type": "archive", |
||||
"url": "https://github.com/jedisct1/libsodium/releases/download/1.0.18-RELEASE/libsodium-1.0.18.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"build-commands": [ |
||||
"./bootstrap.sh --with-libraries=thread,system,iostreams --prefix=/app", |
||||
"./b2 -d0 variant=release link=static threading=multi --layout=system", |
||||
"./b2 -d0 install" |
||||
], |
||||
"buildsystem": "simple", |
||||
"name": "boost", |
||||
"sources": [ |
||||
{ |
||||
"sha256": "59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722", |
||||
"type": "archive", |
||||
"url": "https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.bz2" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"config-opts": [ |
||||
"-DBUILD_LIB_TESTS=OFF", |
||||
"-DBUILD_LIB_EXAMPLES=OFF", |
||||
"-DCMAKE_BUILD_TYPE=Release", |
||||
"-DBUILD_SHARED_LIBS=OFF" |
||||
], |
||||
"buildsystem": "cmake-ninja", |
||||
"name": "mtxclient", |
||||
"sources": [ |
||||
{ |
||||
"sha256": "df3fe7e3d59b5fc52ee3ca9a132a55fc325aa799c676e9e420073c56daeb1848", |
||||
"type": "archive", |
||||
"url": "https://github.com/Nheko-Reborn/mtxclient/archive/5838f607d0e4c7595439249e8b9c213aec0667e9.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"config-opts": [ |
||||
"-DCMAKE_BUILD_TYPE=Release", |
||||
"-DTWEENY_BUILD_DOCUMENTATION=OFF", |
||||
"-DTWEENY_BUILD_EXAMPLES=OFF" |
||||
], |
||||
"buildsystem": "cmake-ninja", |
||||
"name": "tweeny", |
||||
"sources": [ |
||||
{ |
||||
"sha256": "482857256a7235646004682912badb6521d361ed6987c8ebdae7986bf64ce694", |
||||
"type": "archive", |
||||
"url": "https://github.com/mobius3/tweeny/archive/43f4130f7e4a67c19d870b60864bc2862c19b81f.tar.gz" |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
"config-opts": [ |
||||
"-DCMAKE_BUILD_TYPE=Release", |
||||
"-DLMDBXX_INCLUDE_DIR=.deps/lmdbxx" |
||||
], |
||||
"buildsystem": "cmake-ninja", |
||||
"name": "nheko", |
||||
"sources": [ |
||||
{ |
||||
"path": ".", |
||||
"type": "dir", |
||||
"skip": ["build-flatpak"] |
||||
}, |
||||
{ |
||||
"dest": ".deps/lmdbxx", |
||||
"sha256": "93721132bbf5045d38ad62de2997655e9984c48ea5c9886746d42128f4b26fbd", |
||||
"type": "archive", |
||||
"url": "https://github.com/bendiken/lmdbxx/archive/0b43ca87d8cfabba392dfe884eb1edb83874de02.tar.gz" |
||||
} |
||||
] |
||||
} |
||||
] |
||||
} |
@ -1,202 +0,0 @@ |
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
http://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
APPENDIX: How to apply the Apache License to your work. |
||||
|
||||
To apply the Apache License to your work, attach the following |
||||
boilerplate notice, with the fields enclosed by brackets "[]" |
||||
replaced with your own identifying information. (Don't include |
||||
the brackets!) The text should be enclosed in the appropriate |
||||
comment syntax for the file format. We also recommend that a |
||||
file or class name and description of purpose be included on the |
||||
same "printed page" as the copyright notice for easier |
||||
identification within third-party archives. |
||||
|
||||
Copyright [yyyy] [name of copyright owner] |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 373 B |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 728 B After Width: | Height: | Size: 696 B |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 5.2 KiB |
@ -0,0 +1,53 @@ |
||||
import QtQuick 2.6 |
||||
import QtGraphicalEffects 1.0 |
||||
import Qt.labs.settings 1.0 |
||||
|
||||
Rectangle { |
||||
id: avatar |
||||
width: 48 |
||||
height: 48 |
||||
radius: settings.avatar_circles ? height/2 : 3 |
||||
|
||||
Settings { |
||||
id: settings |
||||
category: "user" |
||||
property bool avatar_circles: true |
||||
} |
||||
|
||||
property alias url: img.source |
||||
property string displayName |
||||
|
||||
Text { |
||||
anchors.fill: parent |
||||
text: chat.model.escapeEmoji(String.fromCodePoint(displayName.codePointAt(0))) |
||||
textFormat: Text.RichText |
||||
color: colors.text |
||||
font.pixelSize: avatar.height/2 |
||||
verticalAlignment: Text.AlignVCenter |
||||
horizontalAlignment: Text.AlignHCenter |
||||
visible: img.status != Image.Ready |
||||
} |
||||
|
||||
Image { |
||||
id: img |
||||
anchors.fill: parent |
||||
asynchronous: true |
||||
fillMode: Image.PreserveAspectCrop |
||||
mipmap: true |
||||
smooth: false |
||||
|
||||
sourceSize.width: avatar.width |
||||
sourceSize.height: avatar.height |
||||
|
||||
layer.enabled: true |
||||
layer.effect: OpacityMask { |
||||
maskSource: Rectangle { |
||||
anchors.fill: parent |
||||
width: avatar.width |
||||
height: avatar.height |
||||
radius: settings.avatar_circles ? height/2 : 3 |
||||
} |
||||
} |
||||
} |
||||
color: colors.base |
||||
} |
@ -0,0 +1,26 @@ |
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 2.1 |
||||
import im.nheko 1.0 |
||||
|
||||
Rectangle { |
||||
id: indicator |
||||
color: "transparent" |
||||
width: 16 |
||||
height: 16 |
||||
|
||||
ToolTip.visible: ma.containsMouse && indicator.visible |
||||
ToolTip.text: qsTr("Encrypted") |
||||
|
||||
MouseArea{ |
||||
id: ma |
||||
anchors.fill: parent |
||||
hoverEnabled: true |
||||
} |
||||
|
||||
Image { |
||||
id: stateImg |
||||
anchors.fill: parent |
||||
source: "image://colorimage/:/icons/icons/ui/lock.png?"+colors.buttonText |
||||
} |
||||
} |
||||
|
@ -0,0 +1,29 @@ |
||||
import QtQuick 2.3 |
||||
import QtQuick.Controls 2.3 |
||||
|
||||
Button { |
||||
property string image: undefined |
||||
|
||||
id: button |
||||
|
||||
flat: true |
||||
|
||||
// disable background, because we don't want a border on hover |
||||
background: Item { |
||||
} |
||||
|
||||
Image { |
||||
id: buttonImg |
||||
// Workaround, can't get icon.source working for now... |
||||
anchors.fill: parent |
||||
source: "image://colorimage/" + image + "?" + (button.hovered ? colors.highlight : colors.buttonText) |
||||
} |
||||
|
||||
MouseArea |
||||
{ |
||||
id: mouseArea |
||||
anchors.fill: parent |
||||
onPressed: mouse.accepted = false |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
} |
@ -0,0 +1,32 @@ |
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 2.3 |
||||
|
||||
TextEdit { |
||||
textFormat: TextEdit.RichText |
||||
readOnly: true |
||||
wrapMode: Text.Wrap |
||||
selectByMouse: true |
||||
color: colors.text |
||||
|
||||
onLinkActivated: { |
||||
if (/^https:\/\/matrix.to\/#\/(@.*)$/.test(link)) chat.model.openUserProfile(/^https:\/\/matrix.to\/#\/(@.*)$/.exec(link)[1]) |
||||
else if (/^https:\/\/matrix.to\/#\/(![^\/]*)$/.test(link)) timelineManager.setHistoryView(/^https:\/\/matrix.to\/#\/(!.*)$/.exec(link)[1]) |
||||
else if (/^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.test(link)) { |
||||
var match = /^https:\/\/matrix.to\/#\/(![^\/]*)\/(\$.*)$/.exec(link) |
||||
timelineManager.setHistoryView(match[1]) |
||||
chat.positionViewAtIndex(chat.model.idToIndex(match[2]), ListView.Contain) |
||||
} |
||||
else Qt.openUrlExternally(link) |
||||
} |
||||
MouseArea |
||||
{ |
||||
id: ma |
||||
anchors.fill: parent |
||||
propagateComposedEvents: true |
||||
acceptedButtons: Qt.NoButton |
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor |
||||
} |
||||
|
||||
ToolTip.visible: hoveredLink |
||||
ToolTip.text: hoveredLink |
||||
} |
@ -0,0 +1,39 @@ |
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 2.1 |
||||
import im.nheko 1.0 |
||||
|
||||
Rectangle { |
||||
id: indicator |
||||
property int state: 0 |
||||
color: "transparent" |
||||
width: 16 |
||||
height: 16 |
||||
|
||||
ToolTip.visible: ma.containsMouse && state != MtxEvent.Empty |
||||
ToolTip.text: switch (state) { |
||||
case MtxEvent.Failed: return qsTr("Failed") |
||||
case MtxEvent.Sent: return qsTr("Sent") |
||||
case MtxEvent.Received: return qsTr("Received") |
||||
case MtxEvent.Read: return qsTr("Read") |
||||
default: return "" |
||||
} |
||||
MouseArea{ |
||||
id: ma |
||||
anchors.fill: parent |
||||
hoverEnabled: true |
||||
} |
||||
|
||||
Image { |
||||
id: stateImg |
||||
// Workaround, can't get icon.source working for now... |
||||
anchors.fill: parent |
||||
source: switch (indicator.state) { |
||||
case MtxEvent.Failed: return "image://colorimage/:/icons/icons/ui/remove-symbol.png?" + colors.buttonText |
||||
case MtxEvent.Sent: return "image://colorimage/:/icons/icons/ui/clock.png?" + colors.buttonText |
||||
case MtxEvent.Received: return "image://colorimage/:/icons/icons/ui/checkmark.png?" + colors.buttonText |
||||
case MtxEvent.Read: return "image://colorimage/:/icons/icons/ui/double-tick-indicator.png?" + colors.buttonText |
||||
default: return "" |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,134 @@ |
||||
import QtQuick 2.6 |
||||
import QtQuick.Controls 2.3 |
||||
import QtQuick.Layouts 1.2 |
||||
import QtQuick.Window 2.2 |
||||
|
||||
import im.nheko 1.0 |
||||
|
||||
import "./delegates" |
||||
|
||||
MouseArea { |
||||
id: rowArea |
||||
|
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
height: row.height |
||||
|
||||
hoverEnabled: true |
||||
preventStealing: true |
||||
propagateComposedEvents: true |
||||
acceptedButtons: Qt.NoButton |
||||
|
||||
property bool showButtons: false |
||||
|
||||
Timer { |
||||
running: rowArea.containsMouse |
||||
interval: 150 |
||||
onTriggered: rowArea.state = "showButtons" |
||||
} |
||||
|
||||
states: [ |
||||
State { |
||||
name: "hideButtons" |
||||
when: !rowArea.containsMouse |
||||
PropertyChanges { target: rowArea; showButtons: false; } |
||||
}, |
||||
State { |
||||
name: "showButtons" |
||||
PropertyChanges { target: rowArea; showButtons: true; } |
||||
} |
||||
] |
||||
|
||||
RowLayout { |
||||
id: row |
||||
|
||||
anchors.leftMargin: avatarSize + 4 |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
|
||||
|
||||
Column { |
||||
Layout.fillWidth: true |
||||
Layout.alignment: Qt.AlignTop |
||||
spacing: 4 |
||||
|
||||
// fancy reply, if this is a reply |
||||
Reply { |
||||
visible: model.replyTo |
||||
modelData: chat.model.getDump(model.replyTo) |
||||
userColor: timelineManager.userColor(modelData.userId, colors.window) |
||||
} |
||||
|
||||
// actual message content |
||||
MessageDelegate { |
||||
id: contentItem |
||||
|
||||
width: parent.width |
||||
|
||||
modelData: model |
||||
} |
||||
} |
||||
|
||||
ImageButton { |
||||
visible: rowArea.showButtons |
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop |
||||
Layout.preferredHeight: 16 |
||||
width: 16 |
||||
id: replyButton |
||||
hoverEnabled: true |
||||
|
||||
|
||||
image: ":/icons/icons/ui/mail-reply.png" |
||||
|
||||
ToolTip.visible: hovered |
||||
ToolTip.text: qsTr("Reply") |
||||
|
||||
onClicked: chat.model.replyAction(model.id) |
||||
} |
||||
ImageButton { |
||||
visible: rowArea.showButtons |
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop |
||||
Layout.preferredHeight: 16 |
||||
width: 16 |
||||
id: optionsButton |
||||
hoverEnabled: true |
||||
|
||||
image: ":/icons/icons/ui/vertical-ellipsis.png" |
||||
|
||||
ToolTip.visible: hovered |
||||
ToolTip.text: qsTr("Options") |
||||
|
||||
onClicked: messageContextMenu.show(model.id, model.type, optionsButton) |
||||
|
||||
} |
||||
|
||||
StatusIndicator { |
||||
state: model.state |
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop |
||||
Layout.preferredHeight: 16 |
||||
width: 16 |
||||
} |
||||
|
||||
EncryptionIndicator { |
||||
visible: model.isEncrypted |
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop |
||||
Layout.preferredHeight: 16 |
||||
width: 16 |
||||
} |
||||
|
||||
Text { |
||||
Layout.alignment: Qt.AlignRight | Qt.AlignTop |
||||
text: model.timestamp.toLocaleTimeString("HH:mm") |
||||
color: inactiveColors.text |
||||
|
||||
MouseArea{ |
||||
id: ma |
||||
anchors.fill: parent |
||||
hoverEnabled: true |
||||
} |
||||
|
||||
ToolTip.visible: ma.containsMouse |
||||
ToolTip.text: Qt.formatDateTime(model.timestamp, Qt.DefaultLocaleLongDate) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,309 @@ |
||||
import QtQuick 2.9 |
||||
import QtQuick.Controls 2.3 |
||||
import QtQuick.Layouts 1.2 |
||||
import QtGraphicalEffects 1.0 |
||||
import QtQuick.Window 2.2 |
||||
|
||||
import im.nheko 1.0 |
||||
|
||||
import "./delegates" |
||||
|
||||
Item { |
||||
property var colors: currentActivePalette |
||||
property var systemInactive: SystemPalette { colorGroup: SystemPalette.Disabled } |
||||
property var inactiveColors: currentInactivePalette ? currentInactivePalette : systemInactive |
||||
property int avatarSize: 40 |
||||
|
||||
Menu { |
||||
id: messageContextMenu |
||||
palette: colors |
||||
modal: true |
||||
|
||||
function show(eventId_, eventType_, showAt) { |
||||
eventId = eventId_ |
||||
eventType = eventType_ |
||||
popup(showAt) |
||||
} |
||||
|
||||
property string eventId |
||||
property int eventType |
||||
|
||||
MenuItem { |
||||
text: qsTr("Read receipts") |
||||
onTriggered: chat.model.readReceiptsAction(messageContextMenu.eventId) |
||||
} |
||||
MenuItem { |
||||
text: qsTr("Mark as read") |
||||
} |
||||
MenuItem { |
||||
text: qsTr("View raw message") |
||||
onTriggered: chat.model.viewRawMessage(messageContextMenu.eventId) |
||||
} |
||||
MenuItem { |
||||
text: qsTr("Redact message") |
||||
onTriggered: chat.model.redactEvent(messageContextMenu.eventId) |
||||
} |
||||
MenuItem { |
||||
visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker |
||||
text: qsTr("Save as") |
||||
onTriggered: timelineManager.timeline.saveMedia(messageContextMenu.eventId) |
||||
} |
||||
} |
||||
|
||||
id: timelineRoot |
||||
|
||||
Rectangle { |
||||
anchors.fill: parent |
||||
color: colors.window |
||||
|
||||
Text { |
||||
visible: !timelineManager.timeline && !timelineManager.isInitialSync |
||||
anchors.centerIn: parent |
||||
text: qsTr("No room open") |
||||
font.pointSize: 24 |
||||
color: colors.windowText |
||||
} |
||||
|
||||
BusyIndicator { |
||||
anchors.centerIn: parent |
||||
running: timelineManager.isInitialSync |
||||
height: 200 |
||||
width: 200 |
||||
z: 3 |
||||
} |
||||
|
||||
ListView { |
||||
id: chat |
||||
|
||||
visible: timelineManager.timeline != null |
||||
|
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
anchors.top: parent.top |
||||
anchors.bottom: chatFooter.top |
||||
|
||||
anchors.leftMargin: 4 |
||||
anchors.rightMargin: scrollbar.width |
||||
|
||||
model: timelineManager.timeline |
||||
|
||||
boundsBehavior: Flickable.StopAtBounds |
||||
pixelAligned: true |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
acceptedButtons: Qt.NoButton |
||||
propagateComposedEvents: true |
||||
z: -1 |
||||
onWheel: { |
||||
if (wheel.angleDelta != 0) { |
||||
chat.contentY = chat.contentY - wheel.angleDelta.y |
||||
wheel.accepted = true |
||||
chat.returnToBounds() |
||||
} |
||||
} |
||||
} |
||||
|
||||
Shortcut { |
||||
sequence: StandardKey.MoveToPreviousPage |
||||
onActivated: { chat.contentY = chat.contentY - chat.height / 2; chat.returnToBounds(); } |
||||
} |
||||
Shortcut { |
||||
sequence: StandardKey.MoveToNextPage |
||||
onActivated: { chat.contentY = chat.contentY + chat.height / 2; chat.returnToBounds(); } |
||||
} |
||||
|
||||
ScrollBar.vertical: ScrollBar { |
||||
id: scrollbar |
||||
parent: chat.parent |
||||
anchors.top: chat.top |
||||
anchors.left: chat.right |
||||
anchors.bottom: chat.bottom |
||||
} |
||||
|
||||
spacing: 4 |
||||
verticalLayoutDirection: ListView.BottomToTop |
||||
|
||||
onCountChanged: if (atYEnd) model.currentIndex = 0 // Mark last event as read, since we are at the bottom |
||||
|
||||
delegate: Rectangle { |
||||
// This would normally be previousSection, but our model's order is inverted. |
||||
property bool sectionBoundary: (ListView.nextSection != "" && ListView.nextSection !== ListView.section) || model.index === chat.count - 1 |
||||
|
||||
id: wrapper |
||||
property Item section |
||||
width: chat.width |
||||
height: section ? section.height + timelinerow.height : timelinerow.height |
||||
color: "transparent" |
||||
|
||||
TimelineRow { |
||||
id: timelinerow |
||||
y: section ? section.y + section.height : 0 |
||||
} |
||||
|
||||
onSectionBoundaryChanged: { |
||||
if (sectionBoundary) { |
||||
var properties = { |
||||
'modelData': model.dump, |
||||
'section': ListView.section, |
||||
'nextSection': ListView.nextSection |
||||
} |
||||
section = sectionHeader.createObject(wrapper, properties) |
||||
} else { |
||||
section.destroy() |
||||
section = null |
||||
} |
||||
} |
||||
|
||||
Binding { |
||||
target: chat.model |
||||
property: "currentIndex" |
||||
when: y + height + 2 * chat.spacing > chat.contentY + chat.height && y < chat.contentY + chat.height |
||||
value: index |
||||
delayed: true |
||||
} |
||||
|
||||
} |
||||
|
||||
section { |
||||
property: "section" |
||||
} |
||||
Component { |
||||
id: sectionHeader |
||||
Column { |
||||
property var modelData |
||||
property string section |
||||
property string nextSection |
||||
|
||||
topPadding: 4 |
||||
bottomPadding: 4 |
||||
spacing: 8 |
||||
|
||||
visible: !!modelData |
||||
|
||||
width: parent.width |
||||
height: (section.includes(" ") ? dateBubble.height + 8 + userName.height : userName.height) + 8 |
||||
|
||||
Label { |
||||
id: dateBubble |
||||
anchors.horizontalCenter: parent ? parent.horizontalCenter : undefined |
||||
visible: section.includes(" ") |
||||
text: chat.model.formatDateSeparator(modelData.timestamp) |
||||
color: colors.windowText |
||||
|
||||
height: contentHeight * 1.2 |
||||
width: contentWidth * 1.2 |
||||
horizontalAlignment: Text.AlignHCenter |
||||
background: Rectangle { |
||||
radius: parent.height / 2 |
||||
color: colors.base |
||||
} |
||||
} |
||||
Row { |
||||
height: userName.height |
||||
spacing: 4 |
||||
Avatar { |
||||
width: avatarSize |
||||
height: avatarSize |
||||
url: chat.model.avatarUrl(modelData.userId).replace("mxc://", "image://MxcImage/") |
||||
displayName: modelData.userName |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
onClicked: chat.model.openUserProfile(modelData.userId) |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
} |
||||
|
||||
Text { |
||||
id: userName |
||||
text: chat.model.escapeEmoji(modelData.userName) |
||||
color: timelineManager.userColor(modelData.userId, colors.window) |
||||
textFormat: Text.RichText |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
onClicked: chat.model.openUserProfile(section.split(" ")[0]) |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
Rectangle { |
||||
id: chatFooter |
||||
|
||||
height: Math.max(16, footerContent.height) |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
anchors.bottom: parent.bottom |
||||
z: 3 |
||||
|
||||
color: "transparent" |
||||
|
||||
Column { |
||||
id: footerContent |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
|
||||
Text { |
||||
id: typingDisplay |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
anchors.leftMargin: 10 |
||||
anchors.rightMargin: 10 |
||||
|
||||
text: chat.model ? chat.model.formatTypingUsers(chat.model.typingUsers, colors.window) : "" |
||||
textFormat: Text.RichText |
||||
color: colors.windowText |
||||
} |
||||
|
||||
Rectangle { |
||||
anchors.left: parent.left |
||||
anchors.right: parent.right |
||||
|
||||
id: replyPopup |
||||
|
||||
visible: timelineManager.replyingEvent && chat.model |
||||
// Height of child, plus margins, plus border |
||||
height: replyPreview.height + 10 |
||||
color: colors.base |
||||
|
||||
|
||||
Reply { |
||||
id: replyPreview |
||||
|
||||
anchors.left: parent.left |
||||
anchors.leftMargin: 10 |
||||
anchors.right: closeReplyButton.left |
||||
anchors.rightMargin: 20 |
||||
anchors.bottom: parent.bottom |
||||
|
||||
modelData: chat.model ? chat.model.getDump(timelineManager.replyingEvent) : {} |
||||
userColor: timelineManager.userColor(modelData.userId, colors.window) |
||||
} |
||||
|
||||
ImageButton { |
||||
id: closeReplyButton |
||||
|
||||
anchors.right: parent.right |
||||
anchors.rightMargin: 15 |
||||
anchors.top: replyPreview.top |
||||
hoverEnabled: true |
||||
width: 16 |
||||
height: 16 |
||||
|
||||
image: ":/icons/icons/ui/remove-symbol.png" |
||||
ToolTip.visible: closeReplyButton.hovered |
||||
ToolTip.text: qsTr("Close") |
||||
|
||||
onClicked: timelineManager.closeReply() |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,57 @@ |
||||
import QtQuick 2.6 |
||||
import QtQuick.Layouts 1.2 |
||||
|
||||
Rectangle { |
||||
radius: 10 |
||||
color: colors.base |
||||
height: row.height + 24 |
||||
width: parent ? parent.width : undefined |
||||
|
||||
RowLayout { |
||||
id: row |
||||
|
||||
anchors.centerIn: parent |
||||
width: parent.width - 24 |
||||
|
||||
spacing: 15 |
||||
|
||||
Rectangle { |
||||
id: button |
||||
color: colors.light |
||||
radius: 22 |
||||
height: 44 |
||||
width: 44 |
||||
Image { |
||||
id: img |
||||
anchors.centerIn: parent |
||||
|
||||
source: "qrc:/icons/icons/ui/arrow-pointing-down.png" |
||||
fillMode: Image.Pad |
||||
|
||||
} |
||||
MouseArea { |
||||
anchors.fill: parent |
||||
onClicked: timelineManager.timeline.saveMedia(model.data.id) |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
} |
||||
ColumnLayout { |
||||
id: col |
||||
|
||||
Text { |
||||
Layout.fillWidth: true |
||||
text: model.data.body |
||||
textFormat: Text.PlainText |
||||
elide: Text.ElideRight |
||||
color: colors.text |
||||
} |
||||
Text { |
||||
Layout.fillWidth: true |
||||
text: model.data.filesize |
||||
textFormat: Text.PlainText |
||||
elide: Text.ElideRight |
||||
color: colors.text |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
import QtQuick 2.6 |
||||
|
||||
import im.nheko 1.0 |
||||
|
||||
Item { |
||||
property double tempWidth: Math.min(parent ? parent.width : undefined, model.data.width) |
||||
property double tempHeight: tempWidth * model.data.proportionalHeight |
||||
|
||||
property bool tooHigh: tempHeight > timelineRoot.height / 2 |
||||
|
||||
height: tooHigh ? timelineRoot.height / 2 : tempHeight |
||||
width: tooHigh ? (timelineRoot.height / 2) / model.data.proportionalHeight : tempWidth |
||||
|
||||
Image { |
||||
id: img |
||||
anchors.fill: parent |
||||
|
||||
source: model.data.url.replace("mxc://", "image://MxcImage/") |
||||
asynchronous: true |
||||
fillMode: Image.PreserveAspectFit |
||||
|
||||
MouseArea { |
||||
enabled: model.data.type == MtxEvent.ImageMessage |
||||
anchors.fill: parent |
||||
onClicked: timelineManager.openImageOverlay(model.data.url, model.data.id) |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,94 @@ |
||||
import QtQuick 2.6 |
||||
import im.nheko 1.0 |
||||
|
||||
Item { |
||||
// Workaround to have an assignable global property |
||||
Item { |
||||
id: model |
||||
property var data; |
||||
} |
||||
|
||||
property alias modelData: model.data |
||||
|
||||
height: chooser.childrenRect.height |
||||
|
||||
DelegateChooser { |
||||
id: chooser |
||||
//role: "type" //< not supported in our custom implementation, have to use roleValue |
||||
roleValue: model.data.type |
||||
anchors.fill: parent |
||||
|
||||
DelegateChoice { |
||||
roleValue: MtxEvent.UnknownMessage |
||||
Placeholder { text: "Unretrieved event" } |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.TextMessage |
||||
TextMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.NoticeMessage |
||||
NoticeMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.EmoteMessage |
||||
NoticeMessage { |
||||
formatted: chat.model.escapeEmoji(modelData.userName) + " " + model.data.formattedBody |
||||
color: timelineManager.userColor(modelData.userId, colors.window) |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.ImageMessage |
||||
ImageMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Sticker |
||||
ImageMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.FileMessage |
||||
FileMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.VideoMessage |
||||
PlayableMediaMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.AudioMessage |
||||
PlayableMediaMessage {} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Redacted |
||||
Pill { |
||||
text: qsTr("redacted") |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Encryption |
||||
Pill { |
||||
text: qsTr("Encryption enabled") |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Name |
||||
NoticeMessage { |
||||
text: model.data.roomName ? qsTr("room name changed to: %1").arg(model.data.roomName) : qsTr("removed room name") |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Topic |
||||
NoticeMessage { |
||||
text: model.data.roomTopic ? qsTr("topic changed to: %1").arg(model.data.roomTopic) : qsTr("removed topic") |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
roleValue: MtxEvent.Member |
||||
NoticeMessage { |
||||
text: timelineManager.timeline.formatMemberEvent(model.data.id); |
||||
} |
||||
} |
||||
DelegateChoice { |
||||
Placeholder {} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,4 @@ |
||||
TextMessage { |
||||
font.italic: true |
||||
color: inactiveColors.text |
||||
} |
@ -0,0 +1,14 @@ |
||||
import QtQuick 2.5 |
||||
import QtQuick.Controls 2.1 |
||||
|
||||
Label { |
||||
color: inactiveColors.text |
||||
horizontalAlignment: Text.AlignHCenter |
||||
|
||||
height: contentHeight * 1.2 |
||||
width: contentWidth * 1.2 |
||||
background: Rectangle { |
||||
radius: parent.height / 2 |
||||
color: colors.base |
||||
} |
||||
} |
@ -0,0 +1,7 @@ |
||||
import ".." |
||||
|
||||
MatrixText { |
||||
text: qsTr("unimplemented event: ") + model.data.typeString |
||||
width: parent ? parent.width : undefined |
||||
color: inactiveColors.text |
||||
} |
@ -0,0 +1,167 @@ |
||||
import QtQuick 2.6 |
||||
import QtQuick.Layouts 1.2 |
||||
import QtQuick.Controls 2.1 |
||||
import QtMultimedia 5.6 |
||||
|
||||
import im.nheko 1.0 |
||||
|
||||
Rectangle { |
||||
id: bg |
||||
radius: 10 |
||||
color: colors.base |
||||
height: content.height + 24 |
||||
width: parent ? parent.width : undefined |
||||
|
||||
Column { |
||||
id: content |
||||
width: parent.width - 24 |
||||
anchors.centerIn: parent |
||||
|
||||
Rectangle { |
||||
id: videoContainer |
||||
visible: model.data.type == MtxEvent.VideoMessage |
||||
width: Math.min(parent.width, model.data.width ? model.data.width : 400) // some media has 0 as size... |
||||
height: width*model.data.proportionalHeight |
||||
Image { |
||||
anchors.fill: parent |
||||
source: model.data.thumbnailUrl.replace("mxc://", "image://MxcImage/") |
||||
asynchronous: true |
||||
fillMode: Image.PreserveAspectFit |
||||
|
||||
VideoOutput { |
||||
anchors.fill: parent |
||||
fillMode: VideoOutput.PreserveAspectFit |
||||
source: media |
||||
} |
||||
} |
||||
} |
||||
|
||||
RowLayout { |
||||
width: parent.width |
||||
Text { |
||||
id: positionText |
||||
text: "--:--:--" |
||||
color: colors.text |
||||
} |
||||
Slider { |
||||
Layout.fillWidth: true |
||||
id: progress |
||||
value: media.position |
||||
from: 0 |
||||
to: media.duration |
||||
|
||||
onMoved: media.seek(value) |
||||
//indeterminate: true |
||||
function updatePositionTexts() { |
||||
function formatTime(date) { |
||||
var hh = date.getUTCHours(); |
||||
var mm = date.getUTCMinutes(); |
||||
var ss = date.getSeconds(); |
||||
if (hh < 10) {hh = "0"+hh;} |
||||
if (mm < 10) {mm = "0"+mm;} |
||||
if (ss < 10) {ss = "0"+ss;} |
||||
return hh+":"+mm+":"+ss; |
||||
} |
||||
positionText.text = formatTime(new Date(media.position)) |
||||
durationText.text = formatTime(new Date(media.duration)) |
||||
} |
||||
onValueChanged: updatePositionTexts() |
||||
|
||||
palette: colors |
||||
} |
||||
Text { |
||||
id: durationText |
||||
text: "--:--:--" |
||||
color: colors.text |
||||
} |
||||
} |
||||
|
||||
RowLayout { |
||||
width: parent.width |
||||
|
||||
spacing: 15 |
||||
|
||||
Rectangle { |
||||
id: button |
||||
color: colors.window |
||||
radius: 22 |
||||
height: 44 |
||||
width: 44 |
||||
Image { |
||||
id: img |
||||
anchors.centerIn: parent |
||||
z: 3 |
||||
|
||||
source: "image://colorimage/:/icons/icons/ui/arrow-pointing-down.png?"+colors.text |
||||
fillMode: Image.Pad |
||||
|
||||
} |
||||
MouseArea { |
||||
anchors.fill: parent |
||||
onClicked: { |
||||
switch (button.state) { |
||||
case "": timelineManager.timeline.cacheMedia(model.data.id); break; |
||||
case "stopped": |
||||
media.play(); console.log("play"); |
||||
button.state = "playing" |
||||
break |
||||
case "playing": |
||||
media.pause(); console.log("pause"); |
||||
button.state = "stopped" |
||||
break |
||||
} |
||||
} |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
MediaPlayer { |
||||
id: media |
||||
onError: console.log(errorString) |
||||
onStatusChanged: if(status == MediaPlayer.Loaded) progress.updatePositionTexts() |
||||
onStopped: button.state = "stopped" |
||||
} |
||||
|
||||
Connections { |
||||
target: timelineManager.timeline |
||||
onMediaCached: { |
||||
if (mxcUrl == model.data.url) { |
||||
media.source = "file://" + cacheUrl |
||||
button.state = "stopped" |
||||
console.log("media loaded: " + mxcUrl + " at " + cacheUrl) |
||||
} |
||||
console.log("media cached: " + mxcUrl + " at " + cacheUrl) |
||||
} |
||||
} |
||||
|
||||
states: [ |
||||
State { |
||||
name: "stopped" |
||||
PropertyChanges { target: img; source: "image://colorimage/:/icons/icons/ui/play-sign.png?"+colors.text } |
||||
}, |
||||
State { |
||||
name: "playing" |
||||
PropertyChanges { target: img; source: "image://colorimage/:/icons/icons/ui/pause-symbol.png?"+colors.text } |
||||
} |
||||
] |
||||
} |
||||
ColumnLayout { |
||||
id: col |
||||
|
||||
Text { |
||||
Layout.fillWidth: true |
||||
text: model.data.body |
||||
textFormat: Text.PlainText |
||||
elide: Text.ElideRight |
||||
color: colors.text |
||||
} |
||||
Text { |
||||
Layout.fillWidth: true |
||||
text: model.data.filesize |
||||
textFormat: Text.PlainText |
||||
elide: Text.ElideRight |
||||
color: colors.text |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,58 @@ |
||||
import QtQuick 2.6 |
||||
import QtQuick.Controls 2.3 |
||||
import QtQuick.Layouts 1.2 |
||||
import QtQuick.Window 2.2 |
||||
|
||||
Rectangle { |
||||
id: replyComponent |
||||
|
||||
property alias modelData: reply.modelData |
||||
property color userColor: "red" |
||||
|
||||
width: parent.width |
||||
height: replyContainer.height |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
preventStealing: true |
||||
onClicked: chat.positionViewAtIndex(chat.model.idToIndex(timelineManager.replyingEvent), ListView.Contain) |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
|
||||
Rectangle { |
||||
id: colorLine |
||||
|
||||
anchors.top: replyContainer.top |
||||
anchors.bottom: replyContainer.bottom |
||||
width: 4 |
||||
|
||||
color: timelineManager.userColor(reply.modelData.userId, colors.window) |
||||
} |
||||
|
||||
Column { |
||||
id: replyContainer |
||||
anchors.left: colorLine.right |
||||
anchors.leftMargin: 4 |
||||
width: parent.width - 8 |
||||
|
||||
Text { |
||||
id: userName |
||||
text: chat.model ? chat.model.escapeEmoji(reply.modelData.userName) : "" |
||||
color: replyComponent.userColor |
||||
textFormat: Text.RichText |
||||
|
||||
MouseArea { |
||||
anchors.fill: parent |
||||
onClicked: chat.model.openUserProfile(reply.modelData.userId) |
||||
cursorShape: Qt.PointingHandCursor |
||||
} |
||||
} |
||||
|
||||
MessageDelegate { |
||||
id: reply |
||||
width: parent.width |
||||
} |
||||
} |
||||
|
||||
color: Qt.rgba(userColor.r, userColor.g, userColor.b, 0.2) |
||||
} |
@ -0,0 +1,7 @@ |
||||
import ".." |
||||
|
||||
MatrixText { |
||||
property string formatted: model.data.formattedBody |
||||
text: "<style type=\"text/css\">a { color:"+colors.link+";}</style>" + formatted.replace("<pre>", "<pre style='white-space: pre-wrap'>") |
||||
width: parent ? parent.width : undefined |
||||
} |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
@ -0,0 +1,7 @@ |
||||
# Updating emoji |
||||
|
||||
1. Get the latest emoji-test.txt from here: https://unicode.org/Public/emoji/ |
||||
2. Overwrite the existing resources/emoji-test.txt with the new one |
||||
3. Run `./scripts/emoji_codegen.py resources/emoji-test.txt` and replace the current tail of src/emoji/Provider.cpp with the new output |
||||
4. `make lint` |
||||
5. Compile and test |
@ -0,0 +1,67 @@ |
||||
#pragma once |
||||
|
||||
#include <map> |
||||
#include <mutex> |
||||
|
||||
//#include <nlohmann/json.hpp>
|
||||
|
||||
#include <mtx/responses.hpp> |
||||
#include <mtxclient/crypto/client.hpp> |
||||
|
||||
// Extra information associated with an outbound megolm session.
|
||||
struct OutboundGroupSessionData |
||||
{ |
||||
std::string session_id; |
||||
std::string session_key; |
||||
uint64_t message_index = 0; |
||||
}; |
||||
|
||||
void |
||||
to_json(nlohmann::json &obj, const OutboundGroupSessionData &msg); |
||||
void |
||||
from_json(const nlohmann::json &obj, OutboundGroupSessionData &msg); |
||||
|
||||
struct OutboundGroupSessionDataRef |
||||
{ |
||||
OlmOutboundGroupSession *session; |
||||
OutboundGroupSessionData data; |
||||
}; |
||||
|
||||
struct DevicePublicKeys |
||||
{ |
||||
std::string ed25519; |
||||
std::string curve25519; |
||||
}; |
||||
|
||||
void |
||||
to_json(nlohmann::json &obj, const DevicePublicKeys &msg); |
||||
void |
||||
from_json(const nlohmann::json &obj, DevicePublicKeys &msg); |
||||
|
||||
//! Represents a unique megolm session identifier.
|
||||
struct MegolmSessionIndex |
||||
{ |
||||
//! The room in which this session exists.
|
||||
std::string room_id; |
||||
//! The session_id of the megolm session.
|
||||
std::string session_id; |
||||
//! The curve25519 public key of the sender.
|
||||
std::string sender_key; |
||||
}; |
||||
|
||||
void |
||||
to_json(nlohmann::json &obj, const MegolmSessionIndex &msg); |
||||
void |
||||
from_json(const nlohmann::json &obj, MegolmSessionIndex &msg); |
||||
|
||||
struct OlmSessionStorage |
||||
{ |
||||
// Megolm sessions
|
||||
std::map<std::string, mtx::crypto::InboundGroupSessionPtr> group_inbound_sessions; |
||||
std::map<std::string, mtx::crypto::OutboundGroupSessionPtr> group_outbound_sessions; |
||||
std::map<std::string, OutboundGroupSessionData> group_outbound_session_data; |
||||
|
||||
// Guards for accessing megolm sessions.
|
||||
std::mutex group_outbound_mtx; |
||||
std::mutex group_inbound_mtx; |
||||
}; |