diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 66bde25c..67affd34 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -27,20 +27,21 @@ build-gcc7: - update-alternatives --install /usr/bin/g++ g++ "/usr/bin/${CXX}" 10 - update-alternatives --set gcc "/usr/bin/${CC}" - update-alternatives --set g++ "/usr/bin/${CXX}" + - rm -rf ../.hunter && mv .hunter ../.hunter || true script: - export PATH="/usr/lib/ccache:${PATH}" - export CMAKE_BUILD_PARALLEL_LEVEL=$(cat /proc/cpuinfo | awk '/^processor/{print $3}' | wc -l) - export PATH="/usr/local/bin/:${PATH}" - . "/opt/qt${QT_PKG}/bin/qt${QT_PKG}-env.sh" || true - - mkdir -p .deps/usr .hunter - - mkdir -p build - cmake -GNinja -H. -Bbuild -DCMAKE_INSTALL_PREFIX=.deps/usr - -DHUNTER_ROOT=".hunter" + -DHUNTER_ROOT="../.hunter" -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DUSE_BUNDLED_OPENSSL=ON -DUSE_BUNDLED_LMDB=OFF -DCMAKE_BUILD_TYPE=Release -DHUNTER_CONFIGURATION_TYPES=Release -DCI_BUILD=ON - cmake --build build + after_script: + - mv ../.hunter .hunter cache: key: "$CI_JOB_NAME" paths: @@ -55,13 +56,14 @@ build-macos: - brew reinstall --force python3 - brew bundle --file=./.ci/macos/Brewfile --force --cleanup - pip3 install dmgbuild + - rm -rf ../.hunter && mv .hunter ../.hunter || true script: - export PATH=/usr/local/opt/qt/bin/:${PATH} - export CMAKE_PREFIX_PATH=/usr/local/opt/qt5 - cmake -GNinja -H. -Bbuild -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=.deps/usr - -DHUNTER_ROOT=".hunter" + -DHUNTER_ROOT="../.hunter" -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo -DHUNTER_CONFIGURATION_TYPES=RelWithDebInfo -DUSE_BUNDLED_OPENSSL=ON @@ -69,6 +71,7 @@ build-macos: -DCI_BUILD=ON - cmake --build build after_script: + - mv ../.hunter .hunter - ./.ci/macos/deploy.sh - ./.ci/upload-nightly-gitlab.sh artifacts/nheko-${CI_COMMIT_SHORT_SHA}.dmg artifacts: @@ -143,7 +146,7 @@ linting: image: alpine:latest tags: [docker] before_script: - - apk update && apk add clang make git python3 py3-pip + - apk update && apk add clang-extra-tools make git python3 py3-pip - export PATH="$PATH:/root/.local/bin" - pip3 install --user reuse script: @@ -164,7 +167,7 @@ appimage-amd64: # update appimage-builder (optional) - pip3 install --upgrade git+https://www.opencode.net/azubieta/appimagecraft.git - - apt-get install -y qt5-default qtdeclarative5-dev qttools5-dev qtscript5-dev qtquickcontrols2-5-dev qtmultimedia5-dev libqt5svg5-dev liblmdb-dev libssl-dev git ninja-build qt5keychain-dev libgtest-dev ccache + - apt-get install -y qt5-default qtdeclarative5-dev qttools5-dev qtscript5-dev qtquickcontrols2-5-dev qtmultimedia5-dev libqt5svg5-dev liblmdb-dev libssl-dev git ninja-build qt5keychain-dev libgtest-dev ccache libevent-dev libcurl4-openssl-dev - wget https://github.com/Kitware/CMake/releases/download/v3.19.0/cmake-3.19.0-Linux-x86_64.sh && sh cmake-3.19.0-Linux-x86_64.sh --skip-license --prefix=/usr/local - /usr/sbin/update-ccache-symlinks script: @@ -174,7 +177,6 @@ appimage-amd64: -DHUNTER_ROOT=".hunter" -DHUNTER_ENABLED=ON -DBUILD_SHARED_LIBS=OFF -DHUNTER_CONFIGURATION_TYPES=Release - -DUSE_BUNDLED_BOOST=ON -DUSE_BUNDLED_SPDLOG=ON -DUSE_BUNDLED_OLM=ON -DUSE_BUNDLED_GTEST=OFF @@ -184,8 +186,10 @@ appimage-amd64: -DUSE_BUNDLED_MTXCLIENT=ON -DUSE_BUNDLED_LMDB=OFF -DUSE_BUNDLED_LMDBXX=ON - -DUSE_BUNDLED_TWEENY=ON -DUSE_BUNDLED_QTKEYCHAIN=OFF + -DUSE_BUNDLED_LIBEVENT=OFF + -DUSE_BUNDLED_LIBCURL=OFF + -DUSE_BUNDLED_COEURL=ON - DESTDIR=`pwd`/AppDir ninja -C build install/local - DESTDIR=`pwd`/AppDir ninja -C build _deps/cmark-build/src/install - mkdir -p AppDir/usr/lib/x86_64-linux-gnu AppDir/lib/x86_64-linux-gnu diff --git a/AppImageBuilder.yml b/AppImageBuilder.yml index fab81da9..f83ce90a 100644 --- a/AppImageBuilder.yml +++ b/AppImageBuilder.yml @@ -38,8 +38,11 @@ AppDir: - kimageformat-plugins - libbs2b0 - libbz2-1.0 + - libcurl4 - libelf1 - libexpat1 + - libevent-core-2.1-6 + - libevent-pthreads-2.1-6 - libhogweed4 - libjpeg-turbo8 - libkf5archive5 diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d9d793c..4b023d48 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,29 +18,24 @@ set(CMAKE_POSITION_INDEPENDENT_CODE ON CACHE BOOL "compile as PIC by default") option(HUNTER_ENABLED "Enable Hunter package manager" OFF) include("cmake/HunterGate.cmake") HunterGate( - URL "https://github.com/cpp-pm/hunter/archive/v0.23.288.tar.gz" - SHA1 "6c9b2bc606d86ae31f96a62fc68f0a593024815b" -) + URL "https://github.com/cpp-pm/hunter/archive/v0.23.305.tar.gz" + SHA1 "fc8d7a6dac2fa23681847b3872d88d3839b657b0" + ) -option(USE_BUNDLED_BOOST "Use the bundled version of Boost." ${HUNTER_ENABLED}) -option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." - ${HUNTER_ENABLED}) +option(USE_BUNDLED_SPDLOG "Use the bundled version of spdlog." ${HUNTER_ENABLED}) option(USE_BUNDLED_OLM "Use the bundled version of libolm." ${HUNTER_ENABLED}) -option(USE_BUNDLED_GTEST "Use the bundled version of Google Test." - ${HUNTER_ENABLED}) -option(USE_BUNDLED_CMARK "Use the bundled version of cmark." - ${HUNTER_ENABLED}) -option(USE_BUNDLED_JSON "Use the bundled version of nlohmann json." - ${HUNTER_ENABLED}) -option(USE_BUNDLED_OPENSSL "Use the bundled version of OpenSSL." - OFF) +option(USE_BUNDLED_GTEST "Use the bundled version of Google Test." ${HUNTER_ENABLED}) +option(USE_BUNDLED_CMARK "Use the bundled version of cmark." ${HUNTER_ENABLED}) +option(USE_BUNDLED_JSON "Use the bundled version of nlohmann json." ${HUNTER_ENABLED}) +option(USE_BUNDLED_OPENSSL "Use the bundled version of OpenSSL." OFF) option(USE_BUNDLED_MTXCLIENT "Use the bundled version of the Matrix Client library." ${HUNTER_ENABLED}) -option(USE_BUNDLED_LMDB "Use the bundled version of lmdb." - ${HUNTER_ENABLED}) -option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdb++." - ${HUNTER_ENABLED}) -option(USE_BUNDLED_QTKEYCHAIN "Use the bundled version of Qt5Keychain." +option(USE_BUNDLED_LMDB "Use the bundled version of lmdb." ${HUNTER_ENABLED}) +option(USE_BUNDLED_LMDBXX "Use the bundled version of lmdb++." ${HUNTER_ENABLED}) +option(USE_BUNDLED_QTKEYCHAIN "Use the bundled version of Qt5Keychain." ${HUNTER_ENABLED}) +option(USE_BUNDLED_COEURL "Use a bundled version of the Curl wrapper" ${HUNTER_ENABLED}) +option(USE_BUNDLED_LIBEVENT "Use the bundled version of spdlog." ${HUNTER_ENABLED}) +option(USE_BUNDLED_LIBCURL "Use the bundled version of spdlog." ${HUNTER_ENABLED}) list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") @@ -119,6 +114,38 @@ if (BUILD_DOCS) endif (DOXYGEN_FOUND) endif() +# +## coeurl +# +## Need to repeat all libevent deps?!? +if (USE_BUNDLED_LIBEVENT) + hunter_add_package(Libevent) + find_package(Libevent CONFIG REQUIRED) +else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(libevent_core REQUIRED IMPORTED_TARGET libevent_core) + if (WIN32) + pkg_check_modules(libevent_windows REQUIRED IMPORTED_TARGET libevent_windows) + else() + pkg_check_modules(libevent_pthreads REQUIRED IMPORTED_TARGET + libevent_pthreads) + endif() +endif() + +# curl +if (USE_BUNDLED_LIBCURL) + hunter_add_package(CURL) + find_package(CURL CONFIG REQUIRED) +else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(libcurl REQUIRED IMPORTED_TARGET libcurl) +endif() + +# spdlog +if(USE_BUNDLED_SPDLOG) + hunter_add_package(spdlog) +endif() +find_package(spdlog 1.0.0 CONFIG REQUIRED) # # LMDB @@ -137,7 +164,7 @@ endif() # # Discover Qt dependencies. # -find_package(Qt5 COMPONENTS Core Widgets LinguistTools Concurrent Svg Multimedia Qml QuickControls2 QuickWidgets REQUIRED) +find_package(Qt5 5.12 COMPONENTS Core Widgets LinguistTools Concurrent Svg Multimedia Qml QuickControls2 QuickWidgets REQUIRED) find_package(Qt5QuickCompiler) find_package(Qt5DBus) @@ -156,7 +183,7 @@ if (USE_BUNDLED_QTKEYCHAIN) set(BUILD_TEST_APPLICATION OFF CACHE INTERNAL "") FetchContent_MakeAvailable(qt5keychain) else() -find_package(Qt5Keychain REQUIRED) + find_package(Qt5Keychain REQUIRED) endif() if (APPLE) @@ -238,7 +265,10 @@ set(PROJECT_VERSION ${CPACK_PACKAGE_VERSION}) message(STATUS "Version: ${PROJECT_VERSION}") cmake_host_system_information(RESULT BUILD_HOST QUERY HOSTNAME) -set(BUILD_USER $ENV{USER}) + +include(CheckSymbolExists) +check_symbol_exists(backtrace_symbols_fd "execinfo.h" HAVE_BACKTRACE_SYMBOLS_FD) + configure_file(cmake/nheko.h config/nheko.h) @@ -261,7 +291,7 @@ set(SRC_FILES # Emoji src/emoji/EmojiModel.cpp - src/emoji/Provider.cpp + src/emoji/Provider.cpp # Timeline @@ -301,8 +331,8 @@ set(SRC_FILES src/ui/ToggleButton.cpp src/ui/UserProfile.cpp - # Generic notification stuff - src/notifications/Manager.cpp + # Generic notification stuff + src/notifications/Manager.cpp src/AvatarProvider.cpp src/BlurhashProvider.cpp @@ -339,13 +369,6 @@ set(SRC_FILES include(FeatureSummary) -if(USE_BUNDLED_BOOST) - hunter_add_package(Boost COMPONENTS iostreams system thread) -endif() -find_package(Boost 1.70 REQUIRED - COMPONENTS iostreams - system - thread) if(USE_BUNDLED_OPENSSL) hunter_add_package(OpenSSL) @@ -356,7 +379,7 @@ if(USE_BUNDLED_MTXCLIENT) FetchContent_Declare( MatrixClient GIT_REPOSITORY https://github.com/Nheko-Reborn/mtxclient.git - GIT_TAG 5d2f055ea9403770039ddf66b1900f890cd5cde7 + GIT_TAG 9ecaefe377d4dab688caee186e4a263cb7f105e8 ) set(BUILD_LIB_EXAMPLES OFF CACHE INTERNAL "") set(BUILD_LIB_TESTS OFF CACHE INTERNAL "") @@ -369,7 +392,7 @@ if(USE_BUNDLED_OLM) FetchContent_Declare( Olm GIT_REPOSITORY https://gitlab.matrix.org/matrix-org/olm.git - GIT_TAG 3.1.4 + GIT_TAG 3.2.4 ) set(OLM_TESTS OFF CACHE INTERNAL "") FetchContent_MakeAvailable(Olm) @@ -417,10 +440,10 @@ set_package_properties(nlohmann_json PROPERTIES if(USE_BUNDLED_LMDBXX) include(FetchContent) FetchContent_Declare( - lmdbxx - URL "https://raw.githubusercontent.com/hoytech/lmdbxx/1.0.0/lmdb++.h" - DOWNLOAD_NO_EXTRACT TRUE - ) + lmdbxx + URL "https://raw.githubusercontent.com/hoytech/lmdbxx/1.0.0/lmdb++.h" + DOWNLOAD_NO_EXTRACT TRUE + ) if(NOT lmdbxx_POPULATED) FetchContent_Populate(lmdbxx) endif() @@ -458,7 +481,7 @@ endif() # single instance functionality set(QAPPLICATION_CLASS QApplication CACHE STRING "Inheritance class for SingleApplication") -add_subdirectory(third_party/SingleApplication-3.2.0-dc8042b/) +add_subdirectory(third_party/SingleApplication-3.3.0/) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) @@ -587,6 +610,10 @@ if(WIN32) target_compile_definitions(nheko PRIVATE _WIN32_WINNT=0x0601) else() add_executable (nheko ${OS_BUNDLE} ${NHEKO_DEPS}) + + if (HAVE_BACKTRACE_SYMBOLS_FD AND NOT CMAKE_BUILD_TYPE STREQUAL "Release") + set_target_properties(nheko PROPERTIES ENABLE_EXPORTS ON) + endif() endif() if(APPLE) @@ -604,14 +631,11 @@ target_include_directories(nheko PRIVATE src includes third_party/blurhash third # Fixup bundled keychain include dirs if (USE_BUNDLED_QTKEYCHAIN) -target_include_directories(nheko PRIVATE ${qt5keychain_SOURCE_DIR} ${qt5keychain_BINARY_DIR}) + target_include_directories(nheko PRIVATE ${qt5keychain_SOURCE_DIR} ${qt5keychain_BINARY_DIR}) endif() target_link_libraries(nheko PRIVATE MatrixClient::MatrixClient - Boost::iostreams - Boost::system - Boost::thread cmark::cmark spdlog::spdlog Qt5::Widgets @@ -628,11 +652,11 @@ target_link_libraries(nheko PRIVATE SingleApplication::SingleApplication) if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.16.0") -target_precompile_headers(nheko - PRIVATE - - - ) + target_precompile_headers(nheko + PRIVATE + + + ) endif() if (TARGET PkgConfig::GSTREAMER) @@ -644,6 +668,24 @@ if (TARGET PkgConfig::GSTREAMER) endif() endif() +if(USE_BUNDLED_COEURL) + include(FetchContent) + FetchContent_Declare( + coeurl + GIT_REPOSITORY https://nheko.im/Nheko-Reborn/coeurl.git + GIT_TAG 417821a07cfe4429b08a2efed5e480a498087afd + ) + FetchContent_MakeAvailable(coeurl) + target_link_libraries(nheko PUBLIC coeurl::coeurl) +elseif(coeurl_DIR) + find_package(coeurl CONFIG REQUIRED) + target_link_libraries(nheko PUBLIC coeurl::coeurl) +else() + find_package(PkgConfig REQUIRED) + pkg_check_modules(coeurl REQUIRED IMPORTED_TARGET coeurl) + target_link_libraries(nheko PUBLIC PkgConfig::coeurl) +endif() + if(MSVC) target_link_libraries(nheko PRIVATE ntdll) endif() diff --git a/README.md b/README.md index 87ed7f8b..78f3edfd 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,10 @@ Help us with translations so as many people as possible will be able to use nhek ### Note regarding End-to-End encryption -Currently the implementation is at best a **proof of concept** and it should only be used for -testing purposes. Most importantly, it is missing device verification, so while your messages -and media are encrypted, nheko doesn't verify who gets the messages. +The current implementation works in most cases, but you may need to bootstrap +your cross-signing keys in a different client. The implementation may also still +have bugs, so don't rely on it for security. Online keybackup isn't supported, +but you can use offline keybackup. Most other cases should be fine though. ## Features @@ -114,6 +115,15 @@ with [homebrew](https://brew.sh/): ```sh brew install --cask nheko ``` + +#### Windows + +with [Chocolatey](https://chocolatey.org/): + +```posh +choco install nheko-reborn +``` + ### FAQ ## @@ -127,10 +137,10 @@ brew install --cask nheko - Qt5 (5.12 or greater). Required for overlapping hover handlers in Qml. - CMake 3.15 or greater. (Lower version may work, but may break boost linking) - [mtxclient](https://github.com/Nheko-Reborn/mtxclient) +- [coeurl](https://nheko.im/nheko-reborn/coeurl) - [LMDB](https://symas.com/lightning-memory-mapped-database/) - [lmdb++](https://github.com/hoytech/lmdbxx) - [cmark](https://github.com/commonmark/cmark) 0.29 or greater. -- Boost 1.70 or greater. - [libolm](https://gitlab.matrix.org/matrix-org/olm) - [spdlog](https://github.com/gabime/spdlog) - [GStreamer](https://gitlab.freedesktop.org/gstreamer) 1.18.0 or greater (optional, needed for VoIP support). @@ -154,7 +164,6 @@ If you experience build issues and you are trying to link `mtxclient` library wi The bundle flags are currently: -- USE_BUNDLED_BOOST - USE_BUNDLED_SPDLOG - USE_BUNDLED_OLM - USE_BUNDLED_GTEST @@ -164,7 +173,9 @@ The bundle flags are currently: - USE_BUNDLED_MTXCLIENT - USE_BUNDLED_LMDB - USE_BUNDLED_LMDBXX -- USE_BUNDLED_TWEENY +- USE_BUNDLED_COEURL +- USE_BUNDLED_LIBCURL +- USE_BUNDLED_LIBEVENT A note on bundled OpenSSL: You need to explicitly enable it and it will not be using your system certificate directory by default, if you enable it. You need to override that at runtime with the SSL_CERT_FILE variable. On Windows it will still be using your system certificates though, since it loads them from the system store instead of the OpenSSL directory. diff --git a/appveyor.yml b/appveyor.yml index 4dc986ca..d54fffba 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,8 +15,8 @@ environment: cache: - - c:\hunter\ -> appveyor.yml - - build\_deps -> appveyor.yml + - c:\hunter\ -> appveyor.yml, CMakeLists.txt + - build\_deps -> appveyor.yml, CMakeLists.txt build: verbosity: minimal diff --git a/cmake/nheko.h b/cmake/nheko.h index bf1a54fe..ae28aea9 100644 --- a/cmake/nheko.h +++ b/cmake/nheko.h @@ -1,6 +1,7 @@ namespace nheko { constexpr auto version = "${PROJECT_VERSION}"; -constexpr auto build_user = "${BUILD_USER}@${BUILD_HOST}"; constexpr auto build_os = "${CMAKE_HOST_SYSTEM_NAME}"; constexpr auto enable_debug_log = ${SPDLOG_DEBUG_ON}; } + +# cmakedefine01 HAVE_BACKTRACE_SYMBOLS_FD diff --git a/io.github.NhekoReborn.Nheko.yaml b/io.github.NhekoReborn.Nheko.yaml index d8ea05dc..bfc25c5c 100644 --- a/io.github.NhekoReborn.Nheko.yaml +++ b/io.github.NhekoReborn.Nheko.yaml @@ -16,7 +16,9 @@ finish-args: - --socket=wayland - --socket=x11 - --talk-name=org.freedesktop.Notifications - - --talk-name=org.kde.StatusNotifierWatcher + - --talk-name=org.freedesktop.secrets + - --talk-name=org.freedesktop.StatusNotifierItem + - --talk-name=org.kde.* cleanup: - /include - /bin/mdb* @@ -35,6 +37,19 @@ modules: - prefix=/app no-autogen: true subdir: libraries/liblmdb + - name: libevent + buildsystem: autotools + config-opts: + - --disable-shared + - --prefix=/app + - --disable-openssl + sources: + - sha256: 92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb + type: archive + url: https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz + make-install-args: + - prefix=/app + no-autogen: true - name: cmark buildsystem: cmake-ninja builddir: true @@ -61,9 +76,9 @@ modules: buildsystem: cmake-ninja name: olm sources: - - commit: 6753595300767dd70150831dbbe6f92d64e75038 + - commit: 64afab93645957846d936a19b8501dbd3f2cc4a1 disable-shallow-clone: true - tag: 3.1.4 + tag: 3.2.4 type: git url: https://gitlab.matrix.org/matrix-org/olm.git - config-opts: @@ -85,16 +100,6 @@ modules: - sha256: d51a3a8d3efbb1139d7608e28782ea9efea7e7933157e8ff8184901efd8ee760 type: archive url: https://github.com/nlohmann/json/archive/v3.7.0.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://sourceforge.net/projects/boost/files/boost/1.72.0/boost_1_72_0.tar.bz2 - buildsystem: meson name: gstreamer sources: @@ -140,6 +145,14 @@ modules: tag: 1.18.3 type: git url: https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad.git + - buildsystem: meson + config-opts: + - -Ddefault_library=static + name: coeurl + sources: + - commit: 417821a07cfe4429b08a2efed5e480a498087afd + type: git + url: https://nheko.im/nheko-reborn/coeurl.git - config-opts: - -DBUILD_LIB_TESTS=OFF - -DBUILD_LIB_EXAMPLES=OFF @@ -148,19 +161,9 @@ modules: buildsystem: cmake-ninja name: mtxclient sources: - - commit: 5d2f055ea9403770039ddf66b1900f890cd5cde7 + - commit: 9ecaefe377d4dab688caee186e4a263cb7f105e8 type: git url: https://github.com/Nheko-Reborn/mtxclient.git - - 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 diff --git a/resources/icons/ui/user-friends-solid.svg b/resources/icons/ui/user-friends-solid.svg new file mode 100644 index 00000000..1add45ec --- /dev/null +++ b/resources/icons/ui/user-friends-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/langs/nheko_cs.ts b/resources/langs/nheko_cs.ts index 4339497a..c544bf6d 100644 --- a/resources/langs/nheko_cs.ts +++ b/resources/langs/nheko_cs.ts @@ -53,14 +53,6 @@ - - Cache - - - You joined this room. - - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file @@ -614,7 +617,7 @@ - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password @@ -779,6 +782,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -808,13 +816,13 @@ Example: https://server.my:8787 - + removed - + %1 ended the call. @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 - + Invalid server name @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,75 +1229,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - + Decline + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + RoomSettings @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 - - SideBarActions - - - User settings - - - - - Create new room - - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1590,17 +1703,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1621,12 +1739,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1642,85 +1755,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1777,54 +1830,6 @@ Example: https://server.my:8787 - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1864,7 +1869,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1887,8 +1892,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1896,7 +1901,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2698,23 +2703,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_de.ts b/resources/langs/nheko_de.ts index 40cabcbe..58c209a2 100644 --- a/resources/langs/nheko_de.ts +++ b/resources/langs/nheko_de.ts @@ -17,22 +17,22 @@ You are screen sharing - Du hast deinen Bildschirm freigegeben + Du teilst deinen Bildschirm Hide/Show Picture-in-Picture - Bild in Bild anzeigen/verstecken + Bild-in-Bild Teilen/Verstecken Unmute Mic - Stummschaltung aufheben + Stummschaltung Aufheben Mute Mic - Mikrophon stummschalten + Mikrofon stumm schalten @@ -53,14 +53,6 @@ Abbrechen - - Cache - - - You joined this room. - Du bist dem Raum beigetreten. - - CallInvite @@ -133,30 +125,30 @@ ChatPage - + Failed to invite user: %1 Nutzer konnte nicht eingeladen werden: %1 - + Invited user: %1 Eingeladener Benutzer: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Das Migrieren des Caches auf die aktuelle Version ist fehlgeschlagen. Das kann verschiedene Gründe als Ursache haben. Bitte melde den Fehler und verwende in der Zwischenzeit eine ältere Version. Alternativ kannst du den Cache manuell löschen. - + Confirm join - Beitreten bestätigen + Beitritt bestätigen Do you really want to join %1? - Willst du wirklich %1 betreten? + Möchtest du wirklich %1 beitreten? @@ -164,15 +156,15 @@ Raum %1 erzeugt. - - + + Confirm invite Einladung bestätigen - + Do you really want to invite %1 (%2)? - Willst du wirklich %1 (%2) einladen? + Nutzer %1 (%2) wirklich einladen? @@ -187,12 +179,12 @@ Do you really want to kick %1 (%2)? - Willst du wirklich %1 (%2) kicken? + Nutzer %1 (%2) wirklich kicken? Kicked user: %1 - %1 wurde gekickt. + Gekickter Benutzer: %1 @@ -202,7 +194,7 @@ Do you really want to ban %1 (%2)? - Willst du wirklich %1 (%2) aus dem Raum verbannen? + Nutzer %1 (%2) wirklich bannen? @@ -212,7 +204,7 @@ Banned user: %1 - %1 wurde gebannt. + Gebannter Nutzer: %1 @@ -222,7 +214,7 @@ Do you really want to unban %1 (%2)? - Willst du wirklich den Bann von %1 (%2) zurückziehen? + Bann des Nutzers %1 (%2) wirklich aufheben? @@ -232,22 +224,22 @@ Unbanned user: %1 - Verbannung von %1 wurde aufgehoben. + Verbannung aufgehoben: %1 - + Do you really want to start a private chat with %1? Möchtest du wirklich eine private Konversation mit %1 beginnen? - + Cache migration failed! Migration des Caches fehlgeschlagen! Incompatible cache version - Inkompatible Cacheversion + Inkompatible Version des Caches @@ -255,7 +247,7 @@ Der Cache auf der Festplatte wurde mit einer neueren Nheko - Version angelegt. Bitte aktualisiere Nheko oder entferne den Cache. - + Failed to restore OLM account. Please login again. Wiederherstellung des OLM Accounts fehlgeschlagen. Bitte logge dich erneut ein. @@ -265,13 +257,13 @@ Gespeicherte Nachrichten konnten nicht wiederhergestellt werden. Bitte melde Dich erneut an. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Fehler beim Setup der Verschlüsselungsschlüssel. Servermeldung: %1 %2. Bitte versuche es später erneut. - + Please try to login again: %1 Bitte melde dich erneut an: %1 @@ -283,7 +275,7 @@ You joined the room - Du bist dem Raum beigetreten. + Du hast den Raum betreten @@ -301,55 +293,66 @@ Konnte den Raum nicht verlassen: %1 - + Failed to kick %1 from %2: %3 Kontte %1 nicht aus %2 entfernen: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community - Verstecke Räume mit diesem Tag oder aus dieser Community + + Hide rooms with this tag or from this space by default. + Verstecke Räume mit diesem Tag oder von dieser Gruppe standardmäßig. + + + CommunitiesModel - + All rooms Alle Räume - - Favourite rooms + + Shows all rooms without filtering. + Zeige alle Räume ohne Filter. + + + + Favourites Favoriten - Low priority rooms - Räume niedriger Priorität + Rooms you have favourited. + Favorisierte Räume. + + + + Low Priority + Niedrige Priorität + Rooms with low priority. + Räume niediriger Priorität. + + + Server Notices - Tag translation for m.server_notice Serverbenachrichtigungen - - (tag) - (tag) - - - - (community) - (community) + Messages from your server or administrator. + Nachrichten von deinem Server oder Administrator. CrossSigningSecrets - + Decrypt secrets Geheimnisse entschlüsseln @@ -501,23 +504,23 @@ Encrypted by a verified device - + Verschlüsselt von einem verifizierten Gerät Encrypted by an unverified device, but you have trusted that user so far. - + Von einem unverifizierten Gerät verschlüsselt, Sie haben dem Nutzer jedoch früher schon vertraut. Encrypted by an unverified device - + Von einem unverifizierten Gerät verschlüsselt EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Verschlüsseltes Event (keine Schlüssel zur Entschlüsselung gefunden) -- @@ -529,7 +532,7 @@ -- Verschlüsseltes Event (Schlüssel passt nicht für diesen Nachrichtenindex) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -598,13 +601,13 @@ Forward Message - + Nachricht weiterleiten InputBar - + Select a file Datei auswählen @@ -614,7 +617,7 @@ Alle Dateien (*) - + Failed to upload media. Please try again. Medienupload fehlgeschlagen. Bitte versuche es erneut. @@ -645,10 +648,10 @@ You can also put your homeserver address there, if your server doesn't support .well-known lookup. Example: @user:server.my If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. - Dein Anmeldename. Eine mxid sollte mit einem @ anfangen, gefolgt von dem Benutzernamen. Nach dem Benutzernamen sollten ein Doppelpunkt (:) under der Servername folgen. -Nach dem Doppelpunkt kann alternativ die Serveradresse (mit oder ohne Port) angegeben werden, wenn der Server nicht per .well-known auffindbar ist. + Dein Anmeldename sollte mit einem @ anfangen, gefolgt von deinem Benutzernamen. Nach deinem Benutzernamen sollte ein Doppelpunkt (:) und der Servername folgen. +Nach dem Doppelpunkt kann alternativ die Serveradresse (mit oder ohne Port) angegeben werden, wenn der Server nicht via .well-known auffindbar ist. Beispiel: @benutzer:dein.server -Wenn Nheko deinen Server nicht automatisch erkennen kann, wird es dich nach dem Server fragen. +Wenn Nheko deinen Server nicht automatisch erkennen kann, bekommst du eine Eingabemaske gezeigt in die du die Serverdaten manuell eintragen kannst. @@ -668,7 +671,7 @@ Wenn Nheko deinen Server nicht automatisch erkennen kann, wird es dich nach dem A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. - Ein Name für dieses Gerät. Dieser wird der anderen Seite gezeigt, wenn das Gerät verifiziert wird. Wenn nichts angeben wurde, wird einer generiert. + Ein Name für dieses Gerät, das der anderen Seite gezeigt wird, wenn das Gerät verifiziert wird. Wird nichts angegeben, wird einer generiert. @@ -695,13 +698,13 @@ Beispiel: https://mein.server:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org Du hast eine invalide Matrix ID eingegeben. Normalerwise sehen die so aus: @joe:matrix.org - + Autodiscovery failed. Received malformed response. Automatische Erkennung fehlgeschlagen. Antwort war fehlerhaft. @@ -711,7 +714,7 @@ Beispiel: https://mein.server:8787 Automatische Erkennung fehlgeschlagen. Unbekannter Fehler bei Anfrage .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Benötigte Ansprechpunkte nicht auffindbar. Möglicherweise kein Matrixserver. @@ -726,12 +729,12 @@ Beispiel: https://mein.server:8787 Ein unbekannter Fehler ist aufgetreten. Bitte Homeserverdomain prüfen. - + SSO LOGIN SSO ANMELDUNG - + Empty password Leeres Passwort @@ -785,10 +788,15 @@ Beispiel: https://mein.server:8787 removed topic - Raumthema wurde entfernt + Thema wurde entfernt + %1 changed the room avatar + %1 hat dem Raumavatar geändert + + + %1 created and configured room: %2 %1 hat den Raum erstellt: %2 @@ -858,13 +866,13 @@ Beispiel: https://mein.server:8787 You don't have permission to send messages in this room - + Du darfst hier keine Nachrichten senden MessageView - + Edit Bearbeiten @@ -883,6 +891,76 @@ Beispiel: https://mein.server:8787 Options Optionen + + + &Copy + &Kopieren + + + + Copy &link location + Kopiere &Link + + + + Re&act + Re&agieren + + + + Repl&y + Antwo&rten + + + + &Edit + &Editieren + + + + Read receip&ts + Lesebes&tätigungen + + + + &Forward + &Weiterleiten + + + + &Mark as read + Als gelesen &markieren + + + + View raw message + Zeige rohen Nachrichteninhalt + + + + View decrypted raw message + Zeige rohen, entschlüsselten Nachrichteninhalt + + + + Remo&ve message + Na&chricht löschen + + + + &Save as + &Speichern als + + + + &Open in external program + In externem Pr&ogramm öffnen + + + + Copy link to eve&nt + Link &zu diesem Event kopieren + NewVerificationRequest @@ -1022,7 +1100,7 @@ Beispiel: https://mein.server:8787 Placeholder - + unimplemented event: Unimplementiertes Event: @@ -1030,7 +1108,7 @@ Beispiel: https://mein.server:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Benutze ein separates profil, wodurch mehrere Accounts und Nhekoinstanzen zur gleichen Zeit verwendet werden können. @@ -1048,18 +1126,18 @@ Beispiel: https://mein.server:8787 RegisterPage - + Username Benutzername - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Der Benutzername sollte nicht leer sein und nur aus a-z, 0-9, ., _, =, - und / bestehen. - + Password Passwort @@ -1084,22 +1162,47 @@ Beispiel: https://mein.server:8787 Ein Server, der Registrierungen zulässt. Weil Matrix ein dezentralisiertes Protokoll ist, musst du erst einen Server ausfindig machen oder einen persönlichen Server aufsetzen. - + REGISTER REGISTRIEREN - + No supported registration flows! Keine unterstützten Registrierungsmethoden! - + One or more fields have invalid inputs. Please correct those issues and try again. Mindestens ein Feld hat invalide Werte. Bitte behebe diese Fehler und versuche es erneut. - + + Autodiscovery failed. Received malformed response. + Automatische Erkennung fehlgeschlagen. Antwort war fehlerhaft. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Automatische Erkennung fehlgeschlagen. Unbekannter Fehler bei Anfrage .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Benötigte Ansprechpunkte nicht auffindbar. Möglicherweise kein Matrixserver. + + + + Received malformed response. Make sure the homeserver domain is valid. + Erhaltene Antwort war fehlerhaft. Bitte Homeserverdomain prüfen. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Ein unbekannter Fehler ist aufgetreten. Bitte Homeserverdomain prüfen. + + + Password is not long enough (min 8 chars) Passwort nicht lang genug (mind. 8 Zeichen) @@ -1109,7 +1212,7 @@ Beispiel: https://mein.server:8787 Passwörter stimmen nicht überein - + Invalid server name Ungültiger Servername @@ -1117,88 +1220,126 @@ Beispiel: https://mein.server:8787 ReplyPopup - + Close Schließen Cancel edit - Editieren abbrechen + Bearbeiten abbrechen RoomInfo - + no version stored keine Version gespeichert - RoomInfoListItem + RoomList - - Leave room - Raum verlassen - - - - Tag room as: - Tagge den Raum als: - - - - Favourite - Standard matrix tag for favourites - Favorit - - - - Low Priority - Standard matrix tag for low priority rooms - Niedrige Priorität - - - - Server Notice - Standard matrix tag for server notices - Serverbenachrichtigungen - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Fügt einen Tag hinzu oder entfernt ihn. - - - - New tag... - Add a new tag to the room - Neuer Tag… - - - - New Tag - Tag name prompt title + + New tag Neuer Tag - Tag: - Tag name prompt - Tag: + Enter the tag you want to use: + Gib den Tag, den du verwenden willst, ein: - + + Leave room + Raum verlassen + + + + Tag room as: + Tagge den Raum als: + + + + Favourite + Favorit + + + + Low priority + Niedrige Priorität + + + + Server notice + Serverbenachrichtigung + + + + Create new tag... + Neuen Tag erstellen... + + + Accept Akzeptieren - + Decline Ablehnen + + + Status Message + Statusnachricht + + + + Enter your status message: + Gib deine Statusnachricht ein: + + + + Profile settings + Profileinstellungen + + + + Set status message + Setze eine Statusnachricht + + + + Logout + Abmelden + + + + Start a new chat + Neues Gespräch beginnen + + + + Join a room + Raum betreten + + + + Create a new room + Erstelle einen neuen Raum + + + + Room directory + Raumverzeichnis + + + + User settings + Benutzereinstellungen + RoomSettings @@ -1266,7 +1407,7 @@ Beispiel: https://mein.server:8787 Encryption is currently experimental and things might break unexpectedly. <br> Please take note that it can't be disabled afterwards. - Verschlüsselung ist aktuell experimentell und kann in verschiedenen Fällen zu Fehlern führen.<br>Verschlüsselung kann nachträglich nicht deaktiviert werden. + Verschlüsselung ist derzeit experimentell und könnte unerwartete Probleme verursachen.<br>Bitte beachte, dass dies später nicht mehr deaktiviert werden kann. @@ -1278,9 +1419,7 @@ Beispiel: https://mein.server:8787 Whether or not the client should respond automatically with the session keys upon request. Use with caution, this is a temporary measure to test the E2E implementation until device verification is completed. - Ob Nheko automatisch auf Schlüsselanfragen antwortet. Dies ist ein temporärer -Workaround um, solange die Ende-zu-Ende Verschlüsselung unvollständig ist, um -Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. + Soll der Client automatisch mit den Sitzungsschlüsseln auf Anfragen antworten oder nicht? Bitte mit Vorsicht benutzen, dies ist eine vorübergehende Maßnahme, um die Ende-zu-Ende-Implementierung zu testen, bis die Geräteverifizierung abgeschlossen ist. @@ -1325,13 +1464,13 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. Error while reading file: %1 - Fehler beim Lesen der DateI: %1 + Fehler beim Lesen der Datei: %1 Failed to upload image: %s - Hochladen der Bilddatei fehlgeschlagen: %s + Hochladen des Bildes fehlgeschlagen: %s @@ -1349,23 +1488,23 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. Frame rate: - Wiederholungsrate: + Bildrate: Include your camera picture-in-picture - Eigene Kamera als Bild-im-Bild anzeigen + Deine Kamera Bild-in-Bild anzeigen Request remote camera - Kamera der Gegenstelle anfragen + Entfernte Kamera anfragen View your callee's camera like a regular video call - Zeige die Kamera des Angerufen wie in einem normalen Videoanruf an + Die Kamera Ihres Gesprächspartners wie bei einem normalen Videoanruf betrachten @@ -1388,34 +1527,6 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint.Abbrechen - - SideBarActions - - - User settings - Benutzereinstellungen - - - - Create new room - Neuen Raum erstellen - - - - Join a room - Raum betreten - - - - Start a new chat - Neues Gespräch beginnen - - - - Room directory - Raumverzeichnis - - StatusIndicator @@ -1442,7 +1553,7 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. Success - + Successful Verification Erfolgreiche Verifizierung @@ -1460,7 +1571,7 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. TimelineModel - + Message redaction failed: %1 Nachricht zurückziehen fehlgeschlagen: %1 @@ -1595,24 +1706,29 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint.%1 wurde gebannt. - + + Reason: %1 + Grund: %1 + + + %1 redacted their knock. %1 hat das Anklopfen zurückgezogen. - + You joined this room. Du bist dem Raum beigetreten. - + %1 has changed their avatar and changed their display name to %2. - + %1 hat den eigenen Avatar und Namen geändert zu %2. %1 has changed their display name to %2. - + %1 hat den eigenen Namen geändert zu %2. @@ -1626,12 +1742,7 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint.%1 hat den Raum verlassen, obwohl er gar nicht mehr am Raum teilnahm! - - Reason: %1 - Grund: %1 - - - + %1 knocked. %1 hat angeklopft. @@ -1647,85 +1758,25 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. TimelineView - - Copy - - - - - Copy link location - - - - - React - Reaktion senden - - - - Reply - Antworten - - - - Edit - Bearbeiten - - - - Read receipts - Lesebestätigungen - - - - Forward - - - - - Mark as read - Als gelesen markieren - - - - View raw message - Zeige rohen Nachrichteninhalt - - - - View decrypted raw message - Zeige rohen, entschlüsselten Nachrichteninhalt - - - - Remove message - Nachricht entfernen - - - - Save as - Speichern unter - - - - Open in external program - Öffne in externen Programm - - - - Copy link to event - - - - + No room open Kein Raum geöffnet + + + %1 member(s) + %1 Teilnehmer + + + + Back to room list + Zurück zur Raumliste + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Keinen verschlüsselten Chat mit diesem User gefunden. Erstelle einen verschlüsselten 1:1 Chat mit diesem Nutzer und versuche es erneut. @@ -1782,54 +1833,6 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint.Schließen - - UserInfoWidget - - - Logout - Abmelden - - - - Set custom status message - Setze eine benutzerdefinierte Statusnachricht - - - - Custom status message - Benutzerdefinierter Status - - - - Status: - Status: - - - - User Profile Settings - Profileinstellungen - - - - Set presence automatically - Setze Präsenz automatisch - - - - Online - Online - - - - Unavailable - Nicht verfügbar - - - - Offline - Offline - - UserProfile @@ -1869,9 +1872,9 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint.Verifizierung zurückziehen - + Select an avatar - Wähle einen Avatar + Avatar wählen @@ -1892,8 +1895,8 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. UserSettings - - + + Default Standard @@ -1901,7 +1904,7 @@ Schlüssel auszutauschen, wenn der normale Weg nicht zu funktionieren scheint. UserSettingsPage - + Minimize to tray Ins Benachrichtigungsfeld minimieren @@ -1993,13 +1996,12 @@ Betrifft nur Nachrichten in verschlüsselten Chats. When the window loses focus, the timeline will be blurred. - Verliert das Fenster den Fokus, werden die Nachrichten -verschwommen angezeigt. + Die Zeitliste wird unscharf, wenn das Fenster den Fokus verliert. Privacy screen timeout (in seconds [0 - 3600]) - Zeit bis Blickschutz aktiv wird (in Sekunden [0 - 3600]) + Sichtschutz-Zeitbegrenzung (in Sekunden [0 - 3600]) @@ -2716,23 +2718,10 @@ Medien-Größe: %2 %1 hat einen Anruf beendet - - popups::UserMentions - - - This Room - Dieser Raum - - - - All Rooms - Alle Räume - - utils - + Unknown Message Type Unbekannter Nachrichtentyp diff --git a/resources/langs/nheko_el.ts b/resources/langs/nheko_el.ts index c05c7b3e..d5d5f323 100644 --- a/resources/langs/nheko_el.ts +++ b/resources/langs/nheko_el.ts @@ -53,14 +53,6 @@ Άκυρο - - Cache - - - You joined this room. - - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Διάλεξε ένα αρχείο @@ -614,7 +617,7 @@ Όλα τα αρχεία (*) - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password Κενός κωδικός @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username Όνομα χρήστη - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password Κωδικός @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER ΕΓΓΡΑΦΗ - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) Ο κωδικός δεν αποτελείται από αρκετους χαρακτήρες @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 Οι κωδικοί δεν ταιριίαζουν - + Invalid server name Λανθασμένο όνομα διακομιστή @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,74 +1229,112 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - Βγές - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - Αποδοχή + + Leave room + Βγές - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Αποδοχή + + + Decline - Απόρριψη + Απόρριψη + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 Άκυρο - - SideBarActions - - - User settings - - - - - Create new room - Νέα συνομιλία - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 Έξοδος - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Ελαχιστοποίηση @@ -2697,23 +2702,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_en.ts b/resources/langs/nheko_en.ts index 1fc47995..7d3f8276 100644 --- a/resources/langs/nheko_en.ts +++ b/resources/langs/nheko_en.ts @@ -53,14 +53,6 @@ Cancel - - Cache - - - You joined this room. - You joined this room. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Failed to invite user: %1 - + Invited user: %1 Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join Confirm join @@ -164,13 +156,13 @@ Room %1 created. - - + + Confirm invite Confirm invite - + Do you really want to invite %1 (%2)? Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ Unbanned user: %1 - + Do you really want to start a private chat with %1? Do you really want to start a private chat with %1? - + Cache migration failed! Cache migration failed! @@ -255,7 +247,7 @@ The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - + Failed to restore OLM account. Please login again. Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ Failed to restore save data. Please login again. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 Please try to login again: %1 @@ -301,55 +293,66 @@ Failed to leave room: %1 - + Failed to kick %1 from %2: %3 Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms All rooms - - Favourite rooms - Favourite rooms + + Shows all rooms without filtering. + Shows all rooms without filtering. + + + + Favourites + Favourites - Low priority rooms - Low priority rooms + Rooms you have favourited. + Rooms you have favourited. + + + + Low Priority + Low Priority + Rooms with low priority. + Rooms with low priority. + + + Server Notices - Tag translation for m.server_notice Server Notices - - (tag) - (tag) - - - - (community) - (community) + Messages from your server or administrator. + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Encrypted Event (No keys found for decryption) -- @@ -529,7 +532,7 @@ -- Encrypted Event (Key not valid for this index) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Select a file @@ -614,7 +617,7 @@ All Files (*) - + Failed to upload media. Please try again. Failed to upload media. Please try again. @@ -695,13 +698,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. Autodiscovery failed. Received malformed response. @@ -711,7 +714,7 @@ Example: https://server.my:8787 Autodiscovery failed. Unknown error while requesting .well-known. - + The required endpoints were not found. Possibly not a Matrix server. The required endpoints were not found. Possibly not a Matrix server. @@ -726,12 +729,12 @@ Example: https://server.my:8787 An unknown error occured. Make sure the homeserver domain is valid. - + SSO LOGIN SSO LOGIN - + Empty password Empty password @@ -783,6 +786,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + %1 changed the room avatar + + + %1 created and configured room: %2 %1 created and configured room: %2 @@ -812,13 +820,13 @@ Example: https://server.my:8787 %1 answered the call. - + removed removed - + %1 ended the call. %1 ended the call. @@ -864,7 +872,7 @@ Example: https://server.my:8787 MessageView - + Edit Edit @@ -883,6 +891,76 @@ Example: https://server.my:8787 Options Options + + + &Copy + &Copy + + + + Copy &link location + Copy &link location + + + + Re&act + Re&act + + + + Repl&y + Repl&y + + + + &Edit + &Edit + + + + Read receip&ts + Read receip&ts + + + + &Forward + &Forward + + + + &Mark as read + &Mark as read + + + + View raw message + View raw message + + + + View decrypted raw message + View decrypted raw message + + + + Remo&ve message + Remo&ve message + + + + &Save as + &Save as + + + + &Open in external program + &Open in external program + + + + Copy link to eve&nt + Copy link to eve&nt + NewVerificationRequest @@ -1022,7 +1100,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: unimplemented event: @@ -1030,7 +1108,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1048,18 +1126,18 @@ Example: https://server.my:8787 RegisterPage - + Username Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password Password @@ -1084,22 +1162,47 @@ Example: https://server.my:8787 A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. - + REGISTER REGISTER - + No supported registration flows! No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + Autodiscovery failed. Received malformed response. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Autodiscovery failed. Unknown error while requesting .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + The required endpoints were not found. Possibly not a Matrix server. + + + + Received malformed response. Make sure the homeserver domain is valid. + Received malformed response. Make sure the homeserver domain is valid. + + + + An unknown error occured. Make sure the homeserver domain is valid. + An unknown error occured. Make sure the homeserver domain is valid. + + + Password is not long enough (min 8 chars) Password is not long enough (min 8 chars) @@ -1109,7 +1212,7 @@ Example: https://server.my:8787 Passwords don't match - + Invalid server name Invalid server name @@ -1117,7 +1220,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Close @@ -1130,75 +1233,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored no version stored - RoomInfoListItem + RoomList - + + New tag + New tag + + + + Enter the tag you want to use: + Enter the tag you want to use: + + + Leave room Leave room - + Tag room as: Tag room as: - + Favourite - Standard matrix tag for favourites Favourite - - Low Priority - Standard matrix tag for low priority rooms - Low Priority + + Low priority + Low priority - - Server Notice - Standard matrix tag for server notices - Server Notice + + Server notice + Server notice - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Adds or removes the specified tag. + + Create new tag... + Create new tag... - - New tag... - Add a new tag to the room - New tag… - - - - New Tag - Tag name prompt title - New Tag - - - - Tag: - Tag name prompt - Tag: - - - + Accept Accept - + Decline Decline + + + Status Message + Status Message + + + + Enter your status message: + Enter your status message: + + + + Profile settings + Profile settings + + + + Set status message + Set status message + + + + Logout + Logout + + + + Start a new chat + Start a new chat + + + + Join a room + Join a room + + + + Create a new room + Create a new room + + + + Room directory + Room directory + + + + User settings + User settings + RoomSettings @@ -1388,34 +1529,6 @@ E2E implementation until device verification is completed. Cancel - - SideBarActions - - - User settings - User settings - - - - Create new room - Create new room - - - - Join a room - Join a room - - - - Start a new chat - Start a new chat - - - - Room directory - Room directory - - StatusIndicator @@ -1442,7 +1555,7 @@ E2E implementation until device verification is completed. Success - + Successful Verification Successful Verification @@ -1460,7 +1573,7 @@ E2E implementation until device verification is completed. TimelineModel - + Message redaction failed: %1 Message redaction failed: %1 @@ -1595,17 +1708,22 @@ E2E implementation until device verification is completed. %1 was banned. - + + Reason: %1 + Reason: %1 + + + %1 redacted their knock. %1 redacted their knock. - + You joined this room. You joined this room. - + %1 has changed their avatar and changed their display name to %2. %1 has changed their avatar and changed their display name to %2. @@ -1626,12 +1744,7 @@ E2E implementation until device verification is completed. %1 left after having already left! - - Reason: %1 - Reason: %1 - - - + %1 knocked. %1 knocked. @@ -1647,85 +1760,25 @@ E2E implementation until device verification is completed. TimelineView - - Copy - Copy - - - - Copy link location - Copy link location - - - - React - React - - - - Reply - Reply - - - - Edit - Edit - - - - Read receipts - Read receipts - - - - Forward - Forward - - - - Mark as read - Mark as read - - - - View raw message - View raw message - - - - View decrypted raw message - View decrypted raw message - - - - Remove message - Remove message - - - - Save as - Save as - - - - Open in external program - Open in external program - - - - Copy link to event - Copy link to event - - - + No room open No room open + + + %1 member(s) + %1 member(s) + + + + Back to room list + Back to room list + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1782,54 +1835,6 @@ E2E implementation until device verification is completed. Quit - - UserInfoWidget - - - Logout - Logout - - - - Set custom status message - Set custom status message - - - - Custom status message - Custom status message - - - - Status: - Status: - - - - User Profile Settings - User Profile Settings - - - - Set presence automatically - Set presence automatically - - - - Online - Online - - - - Unavailable - Unavailable - - - - Offline - Offline - - UserProfile @@ -1869,7 +1874,7 @@ E2E implementation until device verification is completed. Unverify - + Select an avatar Select an avatar @@ -1892,8 +1897,8 @@ E2E implementation until device verification is completed. UserSettings - - + + Default Default @@ -1901,7 +1906,7 @@ E2E implementation until device verification is completed. UserSettingsPage - + Minimize to tray Minimize to tray @@ -2716,23 +2721,10 @@ Media size: %2 %1 ended a call - - popups::UserMentions - - - This Room - This Room - - - - All Rooms - All Rooms - - utils - + Unknown Message Type Unknown Message Type diff --git a/resources/langs/nheko_eo.ts b/resources/langs/nheko_eo.ts index b0740534..26a67d49 100644 --- a/resources/langs/nheko_eo.ts +++ b/resources/langs/nheko_eo.ts @@ -6,33 +6,33 @@ Calling... - + Vokante… Connecting... - + Konektante… You are screen sharing - + Vi vidigas vian ekranon Hide/Show Picture-in-Picture - + Kaŝi/Montri bildon en bildo Unmute Mic - + Malsilentigi mikrofonon Mute Mic - + Silentigi mikrofonon @@ -40,25 +40,17 @@ Awaiting Confirmation - + Atendante konfirmon Waiting for other side to complete verification. - + Atendante kontrolon venontan de la alia flanko. Cancel - - - - - Cache - - - You joined this room. - Vi aliĝis ĉi tiun ĉambron. + Nuligi @@ -66,17 +58,17 @@ Video Call - + Vidvoko Voice Call - + Voĉvoko No microphone found. - + Neniu mikrofono troviĝis. @@ -84,42 +76,42 @@ Video Call - + Vidvoko Voice Call - + Voĉvoko Devices - + Aparatoj Accept - + Akcepti Unknown microphone: %1 - + Nekonata mikrofono: %1 Unknown camera: %1 - + Nekonata filmilo: %1 Decline - + Rifuzi No microphone found. - + Neniu mikrofono troviĝis. @@ -127,36 +119,36 @@ Entire screen - + Tuta ekrano ChatPage - + Failed to invite user: %1 - + Malsukcesis inviti uzanton: %1 - + Invited user: %1 - + Invitita uzanto: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Malsukcesis migrado de kaŝmemoro al nuna versio. Tio povas havi diversajn kialojn. Bonvolu raporti eraron kaj dume provi malpli novan version. Alternative, vi povas provi forigi la kaŝmemoron permane. - + Confirm join - + Konfirmu aliĝon Do you really want to join %1? - + Ĉu vi certe volas aliĝi al %1? @@ -165,98 +157,98 @@ Ĉambro %1 farit. - - + + Confirm invite - + Konfirmu inviton - + Do you really want to invite %1 (%2)? - + Ĉu vi certe volas inviti uzanton %1 (%2)? Failed to invite %1 to %2: %3 - + Malsukcesis inviti uzanton %1 al %2: %3 Confirm kick - + Konfirmu forpelon Do you really want to kick %1 (%2)? - + Ĉu vi certe volas forpeli uzanton %1 (%2)? Kicked user: %1 - + Forpelis uzanton: %1 Confirm ban - + Konfirmu forbaron Do you really want to ban %1 (%2)? - + Ĉu vi certe volas forbari uzanton %1 (%2)? Failed to ban %1 in %2: %3 - + Malsukcesis forbari uzanton %1 en %2: %3 Banned user: %1 - + Forbaris uzanton: %1 Confirm unban - + Konfirmu malforbaron Do you really want to unban %1 (%2)? - + Ĉu vi certe volas malforbari uzanton %1 (%2)? Failed to unban %1 in %2: %3 - + Malsukcesis malforbari uzanton %1 en %2: %3 Unbanned user: %1 - + Malforbaris uzanton: %1 - + Do you really want to start a private chat with %1? - + Ĉu vi certe volas komenci privatan babilon kun %1? - + Cache migration failed! - + Malsukcesis migrado de kaŝmemoro! Incompatible cache version - + Neakorda versio de kaŝmemoro The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. - + La kaŝmemoro sur via disko estas pli nova ol kiom ĉi tiu versio de Nheko subtenas. Bonvolu ĝisdatigi la programon aŭ vakigi vian kaŝmemoron. - + Failed to restore OLM account. Please login again. @@ -266,20 +258,20 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Malsukcesis agordi ĉifrajn ŝlosilojn. Respondo de servilo: %1 %2. Bonvolu reprovi poste. - + Please try to login again: %1 - + Bonvolu provi resaluti: %1 Failed to join room: %1 - + Malsukcesis aliĝi al ĉambro: %1 @@ -289,75 +281,86 @@ Failed to remove invite: %1 - + Malsukcesis forigi inviton: %1 Room creation failed: %1 - + Malsukcesis krei ĉambron: %1 Failed to leave room: %1 - + Malsukcesis eliri el ĉambro: %1 - + Failed to kick %1 from %2: %3 + Malsukcesis forpeli uzanton %1 de %2: %3 + + + + CommunitiesList + + + Hide rooms with this tag or from this space by default. - CommunitiesListItem + CommunitiesModel - - Hide rooms with this tag or from this community - - - - + All rooms - Ĉiuj ĉambroj - - - - Favourite rooms - Preferaj ĉambroj + Ĉiuj ĉambroj - Low priority rooms + Shows all rooms without filtering. + + + + + Favourites + Rooms you have favourited. + + + + + Low Priority + Malalta prioritato + + + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets - + Malĉifri sekretojn Enter your recovery key or passphrase to decrypt your secrets: - + Enigu vian rehavan ŝlosilon aŭ pasfrazon por malĉifri viajn sekretojn: @@ -367,12 +370,12 @@ Decryption failed - + Malsukcesis malĉifrado Failed to decrypt secrets with the provided recovery key or passphrase - + Malsukcesis malĉifri sekretojn per la donitaj rehava ŝlosilo aŭ pasfrazo @@ -380,22 +383,22 @@ Verification Code - + Kontrolkodo Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification! - + Bonvolu kontroli la sekvantajn ciferojn. Vi devus vidi la samajn numerojn ambaŭflanke. Se ili malsamas, bonvolu premi «Ili ne akordas!» por nuligi la kontrolon! They do not match! - + Ili ne akordas! They match! - + Ili akordas! @@ -403,12 +406,12 @@ Apply - + Apliki Cancel - + Nuligi @@ -418,7 +421,7 @@ Topic - + Temo @@ -426,7 +429,7 @@ Search - Trovu + Serĉu @@ -474,22 +477,22 @@ Verification Code - + Kontrolkodo Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification! - + Bonvolu kontroli per la jenaj bildosignoj. Vi devus vidi la samajn bildosignojn ambaŭflanke. Se ili malsamas, bonvolu premi «Ili ne akordas!» por nuligi la kontrolon! They do not match! - + Ili ne akordas! They match! - + Ili akordas! @@ -497,28 +500,28 @@ This message is not encrypted! - + Ĉi tiu mesaĝo ne estas ĉifrita! Encrypted by a verified device - + Ĉifrita de kontrolita aparato Encrypted by an unverified device, but you have trusted that user so far. - + Ĉifrita de nekontrolita aparato, sed vi fidis je tiu uzanto ĝis nun. Encrypted by an unverified device - + Ĉifrita de nekontrolita aparato EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -530,7 +533,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -565,33 +568,33 @@ Verification failed - + Malsukcesis kontrolo Other client does not support our verification protocol. - + Alia kliento ne subtenas nian kontrolan protokolon. Key mismatch detected! - + Troviĝis malakordo de ŝlosiloj! Device verification timed out. - + Trafiĝis tempolimo de aparata kontrolo. Other party canceled the verification. - + Aliulo nuligis la kontrolon. Close - + Fermi @@ -605,19 +608,19 @@ InputBar - + Select a file - + Elektu dosieron All Files (*) - Ĉiuj dosieroj (*) + Ĉiuj dosieroj (*) - + Failed to upload media. Please try again. - + Malsukcesis alŝuti vidaŭdaĵojn. Bonvolu reprovi. @@ -625,7 +628,7 @@ Remove - + Forigi @@ -633,12 +636,12 @@ Matrix ID - + Identigilo de Matrikso e.g @joe:matrix.org - + ekz. @tacuo:matrix.org @@ -646,17 +649,19 @@ You can also put your homeserver address there, if your server doesn't support .well-known lookup. Example: @user:server.my If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. - Via ensaluta nomo. + Via saluta nomo. Identigilo de Matrikso devus komenciĝi per @ sekvata de la identigilo de uzanto. Post la identigilo, vi devas meti retnomon post :. Vi ankaŭ povas enmeti adreson de via hejmservilo, se via servilo ne subtenas bone-konatan trovmanieron. +Ekzemplo: @uzanto:servilo.mia +Se Nheko malsukcesas trovi vian hejmservilon, ĝi montros kampon por ĝia permana aldono. Password - Pasvorto + Pasvorto Your password. - + Via pasvorto. @@ -667,42 +672,42 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. Wow, I had to use dictionaries a lot to get this, so there may be a number of mistakes :P - Nomo por ĉi tiu aparato, montrot al aliaj, kiam kontrolant viajn aparatojn. Se neniom provizitis, defaŭlto uzit. + Nomo por ĉi tiu aparato, montrota al aliuloj, kiam oni kontrolos viajn aparatojn. Se vi neniun donos, uziĝos nomo implicita. Homeserver address - + Adreso de hejmservilo server.my:8787 - + servilo.mia:8787 The address that can be used to contact you homeservers client API. Example: https://server.my:8787 API should be valid for the EO translation of application programming interface. - La adreso tiu uzeblas kontakti la klienta API de via hejmservisto. -Ekzemplo: https://servisto.mia:8787 + La adreso per kiu kontakteblas la klienta API de via hejmservilo. +Ekzemplo: https://servilo.mia:8787 LOGIN Maybe shouldn't be imperative? - ENSALUTU + SALUTI - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Vi enigis nevalidan identigilon de Matrikso ekz. @tacuo:matrix.org - + Autodiscovery failed. Received malformed response. @@ -712,7 +717,7 @@ Ekzemplo: https://servisto.mia:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -727,19 +732,19 @@ Ekzemplo: https://servisto.mia:8787 - + SSO LOGIN - SSO ENSALUTU + UNUNURA SALUTO - + Empty password - + Malplena pasvorto SSO login failed - + Malsukcesis ununura saluto @@ -761,7 +766,7 @@ Ekzemplo: https://servisto.mia:8787 removed - + forigita @@ -790,38 +795,43 @@ Ekzemplo: https://servisto.mia:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 placed a voice call. - + %1 metis voĉvokon. %1 placed a video call. - + %1 metis vidvokon. %1 placed a call. - + %1 metis vokon. %1 answered the call. - + %1 respondis la vokon. %1 ended the call. - + %1 finis la vokon. Negotiating call... - + Traktante vokon… @@ -834,7 +844,7 @@ Ekzemplo: https://servisto.mia:8787 Place a call - + Voki @@ -844,45 +854,115 @@ Ekzemplo: https://servisto.mia:8787 Write a message... - Skribu mesaĝon... + Skribu mesaĝon… Emoji - + Bildosignoj Send - Sendu + Sendi You don't have permission to send messages in this room - + Vi ne rajtas sendi mesaĝojn en ĉi tiu ĉambro MessageView - + Edit - + Redakti React - Reagu + Reagi Reply - Respondu + Respondi Options - Ebloj + Elektebloj + + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Vidi krudan mesaĝon + + + + View decrypted raw message + Vidi malĉifritan krudan mesaĝon + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + @@ -890,57 +970,57 @@ Ekzemplo: https://servisto.mia:8787 Send Verification Request - + Sendi kontrolpeton Received Verification Request - + Ricevita kontrolpeto To allow other users to see, which of your devices actually belong to you, you can verify them. This also allows key backup to work automatically. Verify %1 now? - + Por vidigi al aliuloj, kiuj viaj aparatoj vere apartenas al vi, vi povas ilin kontroli. Tio ankaŭ funkciigus memagan savkopiadon de ŝlosiloj. Ĉu vi volas kontroli aparaton %1 nun? To ensure that no malicious user can eavesdrop on your encrypted communications you can verify the other party. - + Por certigi, ke neniu malica uzanto subaŭskultas vian ĉifritan komunikadon, vi povas kontroli la kunparolanton. %1 has requested to verify their device %2. - + %1 petis kontrolon de sia aparato %2. %1 using the device %2 has requested to be verified. - + %1 petis kontrolon per la aparato %2. Your device (%1) has requested to be verified. - + Via aparato (%1) petis kontrolon. Cancel - + Nuligi Deny - + Rifuzi Start verification - + Komenci kontrolon Accept - + Akcepti @@ -950,41 +1030,41 @@ Ekzemplo: https://servisto.mia:8787 %1 sent an encrypted message - + %1 sendis ĉifritan mesaĝon * %1 %2 Format an emote message in a notification, %1 is the sender, %2 the message - + * %1 %2 %1 replied: %2 Format a reply in a notification. %1 is the sender, %2 the message - + %1 respondis: %2 %1: %2 Format a normal message in a notification. %1 is the sender, %2 the message - %1: %2 + %1: %2 %1 replied with an encrypted message - + %1 respondis per ĉifrita mesaĝo %1 replied to a message - + %1 respondis al mesaĝo %1 sent a message - + %1 sendis mesaĝon @@ -992,82 +1072,82 @@ Ekzemplo: https://servisto.mia:8787 Place a call to %1? - + Ĉu voki al %1? No microphone found. - + Neniu mikrofono troviĝis. Voice - + Voĉe Video - + Vide Screen - + Ekrane Cancel - + Nuligi Placeholder - + unimplemented event: - + neprogramita okazo: QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. profile - + profilo profile name - + nomo de profilo RegisterPage - + Username - Uzantnomo + Uzantonomo - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + La uzantonomo devas ne esti malplena, kaj devas enhavi nur la signojn a–z, 0–9, ., _, =, -, kaj /. - + Password Pasvorto Please choose a secure password. The exact requirements for password strength may depend on your server. - + Bonvolu elekti sekuran pasvorton. Precizaj postuloj por ĝia fortikeco povus dependi de via servilo. @@ -1077,202 +1157,265 @@ Ekzemplo: https://servisto.mia:8787 Homeserver - + Hejmservilo A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. - + Servilo, kiu permesas registriĝon. Ĉar Matrikso estas federa, vi bezonas unue trovi servilon, kie vi povus registriĝi, aŭ gastigi vian propran. - + REGISTER - REGISTRU + REGISTRIĜI - + No supported registration flows! - + Neniuj subtenataj manieroj de registriĝo! - + One or more fields have invalid inputs. Please correct those issues and try again. + Unu aŭ pliaj kampoj havas nevalidajn enigojn. Bonvolu korekti la problemojn kaj reprovi. + + + + Autodiscovery failed. Received malformed response. - - Password is not long enough (min 8 chars) + + Autodiscovery failed. Unknown error when requesting .well-known. + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + + Password is not long enough (min 8 chars) + Pasvorto nesufiĉe longas (almenaŭ 8 signoj) + Passwords don't match - + Pasvortoj ne akordas - + Invalid server name - + Nevalida nomo de servilo ReplyPopup - + Close - + Fermi Cancel edit - + Nuligi redakton RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - Eliru ĉambro - - - - Tag room as: + + New tag - - - Favourite - Standard matrix tag for favourites - Preferata - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - Nova etikedo... - - - - New Tag - Tag name prompt title - Nova etikedo - - Tag: - Tag name prompt - Etikedo: + Enter the tag you want to use: + - + + Leave room + Eliri el ĉambro + + + + Tag room as: + Etikedi ĉambron: + + + + Favourite + Preferata + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept + Akcepti + + + + Decline + Rifuzi + + + + Status Message - - Decline + + Enter your status message: + + + Profile settings + + + + + Set status message + + + + + Logout + Adiaŭi + + + + Start a new chat + Komenci novan babilon + + + + Join a room + Aliĝi ĉambron + + + + Create a new room + + + + + Room directory + Ĉambra dosierujo + + + + User settings + Agordoj de uzanto + RoomSettings Room Settings - + Agordoj de ĉambro %1 member(s) - + %1 ĉambrano(j) SETTINGS - + AGORDOJ Notifications - + Sciigoj Muted - + Neniuj Mentions only - + Nur mencioj All messages - + Ĉiuj mesaĝoj Anyone and guests - + Ĉiu ajn, inkluzive gastojn Anyone - + Ĉiu ajn Invited users - + Invititoj Encryption - + Ĉifrado End-to-End Encryption - + Tutvoja ĉifrado Encryption is currently experimental and things might break unexpectedly. <br> Please take note that it can't be disabled afterwards. - + Ĉifrado nun estas eksperimenta kaj povus rompiĝi neatendite.<br>Bonvole sciu, ke ne eblas ĝin malŝalti poste. Respond to key requests - + Respondi al petoj de ŝlosiloj @@ -1284,32 +1427,32 @@ Ekzemplo: https://servisto.mia:8787 INFO - + INFORMOJ Internal ID - + Interna identigilo Room Version - + Versio de ĉambro OK - Bone + Bone Failed to enable encryption: %1 - + Malsukcesis ŝalti ĉifradon: %1 Select an avatar - + Elektu bildon de ĉambro @@ -1319,18 +1462,18 @@ Ekzemplo: https://servisto.mia:8787 The selected file is not an image - + La elektita dosiero ne estas bildo Error while reading file: %1 - + Eraris legado de dosiero: %1 Failed to upload image: %s - + Malsukcesis alŝuti bildon: %s @@ -1338,17 +1481,17 @@ Ekzemplo: https://servisto.mia:8787 Share desktop with %1? - + Ĉu montri la labortablon al %1? Window: - + Fenestro: Frame rate: - + Filmerrapido: @@ -1369,7 +1512,7 @@ Ekzemplo: https://servisto.mia:8787 Hide mouse cursor - + Kaŝi musmontrilon @@ -1384,36 +1527,7 @@ Ekzemplo: https://servisto.mia:8787 Cancel - - - - - SideBarActions - - - User settings - Uzanta agordoj - - - - Create new room - Faru novan ĉambron - - - - Join a room - Aliĝu ĉambron - - - - Start a new chat - Komencu novan babilon - - - - Room directory - Is it correct to use the adjective form in this way or should I use Dosierujo de ĉambro? Or da ĉambro? - Ĉambra dosierujo + Nuligi @@ -1437,13 +1551,13 @@ Ekzemplo: https://servisto.mia:8787 Read Could this simply be "lega"? - Estas lega + Estas legita Success - + Successful Verification @@ -1455,13 +1569,13 @@ Ekzemplo: https://servisto.mia:8787 Close - + Fermi TimelineModel - + Message redaction failed: %1 @@ -1474,22 +1588,22 @@ Ekzemplo: https://servisto.mia:8787 Save image - + Konservi bildon Save video - + Konservi filmon Save audio - + Konservi sonon Save file - + Konservi dosieron @@ -1503,42 +1617,42 @@ Ekzemplo: https://servisto.mia:8787 %1 opened the room to the public. - + %1 malfermis la ĉambron al publiko. %1 made this room require and invitation to join. - + %1 ekpostulis inviton por aliĝoj al la ĉamrbo. %1 made the room open to guests. - + %1 malfermis la ĉambron al gastoj. %1 has closed the room to guest access. - + %1 fermis la ĉambron al gastoj. %1 made the room history world readable. Events may be now read by non-joined people. - + %1 legebligis historion de la ĉambro al ĉiu ajn. Okazoj nun legeblos al nealiĝintoj. %1 set the room history visible to members from this point on. - + %1 videbligis historion de la ĉambro al ĉiuj ĉambranoj ekde nun. %1 set the room history visible to members since they were invited. - + %1 videbligis historion de la ĉambro al ĉambranoj ekde ties invito. %1 set the room history visible to members since they joined the room. - + %1 videbligis historion de la ĉambro al ĉambranoj ekde ties aliĝo. @@ -1549,13 +1663,13 @@ Ekzemplo: https://servisto.mia:8787 %1 was invited. %1 estis invitata. - + %1 estis invitita. %1 changed their avatar. %1 ŝanĝis sian avataron. - + %1 ŝanĝis sian profilbildon. @@ -1580,7 +1694,7 @@ Ekzemplo: https://servisto.mia:8787 %1 left the room. - %1 eliris la ĉambro. + %1 eliris el la ĉambro. @@ -1598,17 +1712,22 @@ Ekzemplo: https://servisto.mia:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. Vi aliĝis ĉi tiun ĉambron. - + %1 has changed their avatar and changed their display name to %2. @@ -1626,15 +1745,10 @@ Ekzemplo: https://servisto.mia:8787 %1 left after having already left! This is a leave event after the user already left and shouldn't happen apart from state resets - %1 eliris post ili jam eliris! + %1 eliris jam elirinte! - - Reason: %1 - Kialo: %1 - - - + %1 knocked. @@ -1644,91 +1758,31 @@ Ekzemplo: https://servisto.mia:8787 Edited - + Redaktita TimelineView - - Copy - - - - - Copy link location - - - - - React - Reagu - - - - Reply - Respondu - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + %1 ĉambrano(j) + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1764,12 +1818,12 @@ Ekzemplo: https://servisto.mia:8787 Leave room - Eliru ĉambro + Eliri el ĉambro Settings - Agordoj + Agordoj @@ -1777,7 +1831,7 @@ Ekzemplo: https://servisto.mia:8787 Show - Montru + Montri @@ -1785,54 +1839,6 @@ Ekzemplo: https://servisto.mia:8787 - - UserInfoWidget - - - Logout - Elsalutu - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1872,9 +1878,9 @@ Ekzemplo: https://servisto.mia:8787 - + Select an avatar - + Elektu profilbildon @@ -1884,19 +1890,19 @@ Ekzemplo: https://servisto.mia:8787 The selected file is not an image - + La elektita dosiero ne estas bildo Error while reading file: %1 - + Eraris legado de dosiero: %1 UserSettings - - + + Default @@ -1904,7 +1910,7 @@ Ekzemplo: https://servisto.mia:8787 UserSettingsPage - + Minimize to tray @@ -1936,7 +1942,7 @@ Ekzemplo: https://servisto.mia:8787 CALLS - + VOKOJ @@ -1946,142 +1952,159 @@ Ekzemplo: https://servisto.mia:8787 REQUEST - + PETI DOWNLOAD - + ELŜUTI Keep the application running in the background after closing the client window. - + Daŭrigi la aplikaĵon fone post fermo de la klienta fenestro. Start the application in the background without showing the client window. - + Ekigi la aplikaĵon fone sen montro de la klienta fenestro. Change the appearance of user avatars in chats. OFF - square, ON - Circle. - + Ŝanĝas la aspekton de profilbildoj de uzantoj en babilujo. +NE – kvadrataj, JES – rondaj. Show a column containing groups and tags next to the room list. - + Montras kolumnon kun grupoj kaj etikedoj apud la listo de ĉambroj. Decrypt messages in sidebar - + Malĉifri mesaĝojn en flanka breto Decrypt the messages shown in the sidebar. Only affects messages in encrypted chats. - + Malĉifras mesaĝojn montratajn en la flanka breto. +Influas nur sur mesaĝoj en ĉifritaj babiloj. Privacy Screen - + Privateca ŝirmilo When the window loses focus, the timeline will be blurred. - + Kiam la fenestro ne estos fokusata, la historio +malklariĝos. Privacy screen timeout (in seconds [0 - 3600]) - + Atendo ĝis privateca ŝirmilo (0–3600 sekundoj) Set timeout (in seconds) for how long after window loses focus before the screen will be blurred. Set to 0 to blur immediately after focus loss. Max value of 1 hour (3600 seconds) - + Tempo de atendo (en sekundoj) ekde senfokusiĝo +de la fenestro, post kiu la enhavo malklariĝos. +Agordu al 0 por malklarigi enhavon tuj post senfokusiĝo. +Maksimuma valoro estas 1 horo (3600 sekundoj). Show buttons in timeline - + Montri butonojn en historio Show buttons to quickly reply, react or access additional options next to each message. - + Montras butonojn apud ĉiu mesaĝo, por rapide respondi, reagi, +aŭ meti aliajn elekteblojn. Limit width of timeline - + Limigi larĝecon de historio Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised - + Agordas maksimuman larĝecon por mesaĝoj en la historio (en bilderoj). +Tio povas helpi legeblecon sur larĝaj ekranoj, kiam la fenestro de Nheko grandas. Typing notifications - + Sciigoj pri tajpado Show who is typing in a room. This will also enable or disable sending typing notifications to others. - + Montri, kiu tajpas en ĉambro. +Ĉi tio ankaŭ ŝaltos sciigadon pri via tajpado al aliaj. Sort rooms by unreads - + Ordigi ĉambrojn laŭ nelegiteco Display rooms with new messages first. If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. - + Montras ĉambrojn kun novaj mesaĝoj kiel la unuajn. +Kun ĉi tio malŝaltita, la listo de ĉambroj ordiĝos nur laŭ +tempo de la lasta mesaĝo en ĉambro. +Kun ĉi tio ŝaltita, ĉambroj kun aktivaj sciigoj (eta cirklo +kun nombro skribita ene) estos ordigitaj plej supre. Ĉambroj, +kiujn vi silentigis, ankoraŭ estos ordigitaj laŭ tempo, ĉar vi +probable ne pensas ilin same gravaj kiel la aliaj ĉambroj. Read receipts - + Kvitancoj Show if your message was read. Status is displayed next to timestamps. - + Montras, ĉu via mesaĝo estis legita. +Stato estas montrita apud tempindikoj. Send messages as Markdown - + Sendi mesaĝojn Markdaŭne Allow using markdown in messages. When disabled, all messages are sent as a plain text. - + Permesas uzon de Markdaŭno en mesaĝoj. +Kun ĉi tio malŝaltita, ĉiuj mesaĝoj sendiĝas en plata teksto. Desktop notifications - + Labortablaj sciigoj Notify about received message when the client is not currently focused. - + Sciigi pri ricevitaj mesaĝoj kiam la kliento ne estas fokusata. @@ -2297,12 +2320,12 @@ This usually causes the application icon in the task bar to animate in some fash Select a file - + Elektu dosieron All Files (*) - Ĉiuj dosieroj (*) + Ĉiuj dosieroj (*) @@ -2372,7 +2395,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi @@ -2381,7 +2404,7 @@ This usually causes the application icon in the task bar to animate in some fash Welcome to nheko! The desktop client for the Matrix protocol. Should "Matrico" be "Matrica"? (I don't think so) - Bonvenon al nheko! La labortabla kliento por la Matrico protokolo. + Bonvenon al nheko! La labortabla kliento por la protokolo Matrikso. @@ -2396,7 +2419,7 @@ This usually causes the application icon in the task bar to animate in some fash LOGIN - ENSALUTU + SALUTI @@ -2412,12 +2435,12 @@ This usually causes the application icon in the task bar to animate in some fash Create room - Faru ĉambron + Fari ĉambron Cancel - + Nuligi @@ -2427,7 +2450,7 @@ This usually causes the application icon in the task bar to animate in some fash Topic - + Temo @@ -2460,7 +2483,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi @@ -2478,7 +2501,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi @@ -2491,12 +2514,12 @@ This usually causes the application icon in the task bar to animate in some fash Join - Aliĝu + Aliĝi Cancel - + Nuligi @@ -2509,7 +2532,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi @@ -2522,12 +2545,12 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi Logout. Are you sure? - Elsalutu. Ĉu vi certas? + Adiaŭi. Ĉu vi certas? @@ -2540,7 +2563,7 @@ This usually causes the application icon in the task bar to animate in some fash Cancel - + Nuligi @@ -2555,7 +2578,7 @@ Media size: %2 Cancel - + Nuligi @@ -2573,12 +2596,12 @@ Media size: %2 Read receipts - + Kvitancoj Close - + Fermi @@ -2629,22 +2652,22 @@ Media size: %2 You sent a video - Vi sendis videon + Vi sendis filmon %1 sent a video - %1 sendis videon + %1 sendis filmon You sent a sticker - Vi sendis pegatinan + Vi sendis glumarkon %1 sent a sticker - %1 sendis pegatinan + %1 sendis glumarkon @@ -2674,7 +2697,7 @@ Media size: %2 %1 sent an encrypted message - + %1 sendis ĉifritan mesaĝon @@ -2707,23 +2730,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - Ĉi tiu ĉambro - - - - All Rooms - Ĉiuj ĉambroj - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_es.ts b/resources/langs/nheko_es.ts index 7e9fc4c6..6318b9c4 100644 --- a/resources/langs/nheko_es.ts +++ b/resources/langs/nheko_es.ts @@ -53,14 +53,6 @@ Cancelar - - Cache - - - You joined this room. - Te has unido a esta sala. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 No se pudo invitar al usuario: %1 - + Invited user: %1 Usuario invitado: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + La migración de la caché a la versión actual ha fallado. Esto puede deberse a distintos motivos. Por favor, reporte el incidente y mientras tanto intente usar una versión anterior. También puede probar a borrar la caché manualmente. - + Confirm join @@ -161,16 +153,16 @@ Room %1 created. - + Sala %1 creada. - - + + Confirm invite - + Confirmar invitación - + Do you really want to invite %1 (%2)? @@ -182,7 +174,7 @@ Confirm kick - + Confirmar expulsión @@ -192,7 +184,7 @@ Kicked user: %1 - + Se ha expulsado a %1 @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file @@ -614,7 +617,7 @@ - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password @@ -779,6 +782,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -808,13 +816,13 @@ Example: https://server.my:8787 - + removed - + %1 ended the call. @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 - + Invalid server name @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,75 +1229,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept Aceptar - + Decline Rechazar + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + RoomSettings @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 Cancelar - - SideBarActions - - - User settings - - - - - Create new room - - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1599,17 +1712,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. Te has unido a esta sala. - + Rejected the knock from %1. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2697,23 +2702,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_et.ts b/resources/langs/nheko_et.ts index c95cb1a5..198ec332 100644 --- a/resources/langs/nheko_et.ts +++ b/resources/langs/nheko_et.ts @@ -53,14 +53,6 @@ Katkesta - - Cache - - - You joined this room. - Sa liitusid selle jututoaga. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Kutse saatmine kasutajale ei õnnestunud: %1 - + Invited user: %1 Kutsutud kasutaja: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Puhverdatud andmete muutmine sobivaks rakenduse praeguse versiooniga ei õnnestunud. Sellel võib olla erinevaid põhjuseid. Palun saada meile veateade ja seni kasuta vanemat rakenduse versiooni. Aga kui sa soovid proovida, siis kustuta puhverdatud andmed käsitsi. - + Confirm join Kinnita liitumine @@ -164,13 +156,13 @@ %1 jututuba on loodud. - - + + Confirm invite Kinnita kutse - + Do you really want to invite %1 (%2)? Kas sa tõesti soovid saata kutset kasutajale %1 (%2)? @@ -235,12 +227,12 @@ Suhtluskeeld eemaldatud: %1 - + Do you really want to start a private chat with %1? Kas sa kindlasti soovid alustada otsevestlust kasutajaga %1? - + Cache migration failed! Puhvri versiooniuuendus ebaõnnestus! @@ -255,7 +247,7 @@ Sinu andmekandjale salvestatud puhvri versioon on uuem, kui käesolev Nheko versioon kasutada oskab. Palun tee Nheko uuendus või kustuta puhverdatud andmed. - + Failed to restore OLM account. Please login again. OLM konto taastamine ei õnnestunud. Palun logi uuesti sisse. @@ -265,13 +257,13 @@ Salvestatud andmete taastamine ei õnnestunud. Palun logi uuesti sisse. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Krüptovõtmete kasutusele võtmine ei õnnestunud. Koduserveri vastus päringule: %1 %2. Palun proovi hiljem uuesti. - + Please try to login again: %1 Palun proovi uuesti sisse logida: %1 @@ -301,55 +293,66 @@ Jututoast lahkumine ei õnnestunud: %1 - + Failed to kick %1 from %2: %3 Kasutaja %1 väljamüksamine %2 jututoast ei õnnestunud: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community - Peida sellest kogukonnast antud sildiga jututoad + + Hide rooms with this tag or from this space by default. + Vaikimisi peida selle sildiga jututoad. + + + CommunitiesModel - + All rooms Kõik jututoad - - Favourite rooms - Eelistatud jututoad + + Shows all rooms without filtering. + Näita kõiki jututubasid nii, et filter pole kasutusel. + + + + Favourites + Lemmikud - Low priority rooms - Vähetähtsad jututoad + Rooms you have favourited. + Jututoad, mis sa oled märkinud lemmikuteks. + + + + Low Priority + Vähetähtis + Rooms with low priority. + Väheolulised jututoad. + + + Server Notices - Tag translation for m.server_notice Serveriteated - - (tag) - (silt) - - - - (community) - (kogukond) + Messages from your server or administrator. + Sõnumid sinu serverilt või selle haldajalt. CrossSigningSecrets - + Decrypt secrets Dekrüpti andmed @@ -501,23 +504,23 @@ Encrypted by a verified device - + Krüptitud verifitseeritud seadmes Encrypted by an unverified device, but you have trusted that user so far. - + Krüptitud verifitseerimata seadmes, aga sa oled selle kasutajat seni usaldanud. Encrypted by an unverified device - + Krüptitud verifitseerimata seadmes EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Krüptitud sündmus (Dekrüptimisvõtmeid ei leidunud) -- @@ -529,7 +532,7 @@ -- Krüptitud sündmus (võti pole selle indeksi jaoks sobilik) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -598,13 +601,13 @@ Forward Message - + Suuna sõnum edasi InputBar - + Select a file Vali fail @@ -614,7 +617,7 @@ Kõik failid (*) - + Failed to upload media. Please try again. Meediafailide üleslaadimine ei õnnestunud. Palun proovi uuesti. @@ -695,13 +698,13 @@ Näiteks: https://server.minu:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org Sisestatud Matrix'i kasutajatunnus on vigane - peaks olema @kasutaja:server.tld - + Autodiscovery failed. Received malformed response. Koduserveri automaatne tuvastamine ei õnnestunud: päringuvastus oli vigane. @@ -711,7 +714,7 @@ Näiteks: https://server.minu:8787 Koduserveri automaatne tuvastamine ei õnnestunud: tundmatu viga .well-known päringu tegemisel. - + The required endpoints were not found. Possibly not a Matrix server. Protokolli järgi nõutavaid lõpppunkte ei leidunud. Ilmselt pole tegemist Matrix'i serveriga. @@ -726,12 +729,12 @@ Näiteks: https://server.minu:8787 Tekkis teadmata viga. Palun kontrolli, et koduserveri domeen on õige. - + SSO LOGIN ÜHEKORDNE SISSELOGIMINE - + Empty password Tühi salasõna @@ -783,6 +786,11 @@ Näiteks: https://server.minu:8787 + %1 changed the room avatar + %1 muutis jututoa tunnuspilti + + + %1 created and configured room: %2 %1 lõi ja seadistas jututoa: %2 @@ -812,13 +820,13 @@ Näiteks: https://server.minu:8787 %1 vastas kõnele. - + removed eemaldatud - + %1 ended the call. %1 lõpetas kõne. @@ -858,13 +866,13 @@ Näiteks: https://server.minu:8787 You don't have permission to send messages in this room - + Sul puuduvad selles jututoas õigused sõnumite saatmiseks MessageView - + Edit Muuda @@ -883,6 +891,76 @@ Näiteks: https://server.minu:8787 Options Valikud + + + &Copy + &Kopeeri + + + + Copy &link location + Kopeeri &lingi asukoht + + + + Re&act + Re&ageeri + + + + Repl&y + &Vasta + + + + &Edit + &Muuda + + + + Read receip&ts + Lugemis&teatised + + + + &Forward + &Edasta + + + + &Mark as read + &Märgi loetuks + + + + View raw message + Näita sõnumi lähtekoodi + + + + View decrypted raw message + Näita sõnumi dekrüptitud lähtekoodi + + + + Remo&ve message + Eemal&da sõnum + + + + &Save as + &Salvesta kui + + + + &Open in external program + &Ava välise rakendusega + + + + Copy link to eve&nt + Kopeeri sündmuse li&nk + NewVerificationRequest @@ -1022,7 +1100,7 @@ Näiteks: https://server.minu:8787 Placeholder - + unimplemented event: implementeerimata sündmus: @@ -1030,7 +1108,7 @@ Näiteks: https://server.minu:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Loo unikaalne profiil, mis võimaldab sul logida samaaegselt sisse erinevatele kasutajakontodele ning käivitada mitu Nheko programmiakent. @@ -1048,18 +1126,18 @@ Näiteks: https://server.minu:8787 RegisterPage - + Username Kasutajanimi - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Kasutajanimi ei tohi olla tühi ning võib sisaldada vaid a-z, 0-9, ., _, =, -, / tähemärke. - + Password Salasõna @@ -1084,22 +1162,47 @@ Näiteks: https://server.minu:8787 See on server, kus sa oma kasutajakonto registreerid. Kuna Matrix on hajutatud suhtlusvõrk, siis esmalt pead leidma sulle sobiliku koduserveri või panema püsti täitsa oma enda koduserveri. - + REGISTER REGISTREERI - + No supported registration flows! Selline registreerimise töövoog pole toetatud! - + One or more fields have invalid inputs. Please correct those issues and try again. Ühel või enamal andmeväljal on vigane väärtus. Palun paranda vead ja proovi uuesti. - + + Autodiscovery failed. Received malformed response. + Koduserveri automaatne tuvastamine ei õnnestunud: päringuvastus oli vigane. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Koduserveri automaatne tuvastamine ei õnnestunud: tundmatu viga .well-known päringu tegemisel. + + + + The required endpoints were not found. Possibly not a Matrix server. + Protokolli järgi nõutavaid lõpppunkte ei leidunud. Ilmselt pole tegemist Matrix'i serveriga. + + + + Received malformed response. Make sure the homeserver domain is valid. + Päringule sain tagasi vigase vastuse. Palun kontrolli, et koduserveri domeen oleks õige. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Tekkis teadmata viga. Palun kontrolli, et koduserveri domeen on õige. + + + Password is not long enough (min 8 chars) Salasõna pole piisavalt pikk (vähemalt 8 tähemärki) @@ -1109,7 +1212,7 @@ Näiteks: https://server.minu:8787 Salasõnad ei klapi omavahel - + Invalid server name Vigane koduserveri nimi @@ -1117,7 +1220,7 @@ Näiteks: https://server.minu:8787 ReplyPopup - + Close Sulge @@ -1130,74 +1233,112 @@ Näiteks: https://server.minu:8787 RoomInfo - + no version stored salvestatud versiooni ei leidu - RoomInfoListItem + RoomList - - Leave room - Lahku jututoast - - - - Tag room as: - Lisa jututoale silt: - - - - Favourite - Standard matrix tag for favourites - Lemmik - - - - Low Priority - Standard matrix tag for low priority rooms - Vähetähtis - - - - Server Notice - Standard matrix tag for server notices - Serveriteade - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Lisab või eemaldab selle sildi. - - - - New tag... - Add a new tag to the room - Uus silt… - - - - New Tag - Tag name prompt title + + New tag Uus silt - Tag: - Tag name prompt - Silt: + Enter the tag you want to use: + Kirjuta silt, mida soovid kasutada: - + + Leave room + Lahku jututoast + + + + Tag room as: + Lisa jututoale silt: + + + + Favourite + Lemmik + + + + Low priority + Vähetähtis + + + + Server notice + Serveriteade + + + + Create new tag... + Loo uus silt... + + + Accept Nõustu - + Decline - Ei nõustu + Keeldu + + + + Status Message + Olekuteade + + + + Enter your status message: + Sisesta oma olekuteade: + + + + Profile settings + Profiili seadistused + + + + Set status message + Sisesta olekuteade + + + + Logout + Logi välja + + + + Start a new chat + Alusta uut vestlust + + + + Join a room + Liitu jututoaga + + + + Create a new room + Loo uus jututuba + + + + Room directory + Jututubade loend + + + + User settings + Kasutaja seadistused @@ -1388,34 +1529,6 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Loobu - - SideBarActions - - - User settings - Kasutaja seadistused - - - - Create new room - Loo uus jututuba - - - - Join a room - Liitu jututoaga - - - - Start a new chat - Alusta uut vestlust - - - - Room directory - Jututubade loend - - StatusIndicator @@ -1442,7 +1555,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Success - + Successful Verification Verifitseerimine õnnestus @@ -1460,7 +1573,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineModel - + Message redaction failed: %1 Sõnumi ümbersõnastamine ebaõnnestus: %1 @@ -1595,24 +1708,29 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Kasutaja %1 sai suhtluskeelu. - + + Reason: %1 + Põhjus: %1 + + + %1 redacted their knock. %1 muutis oma koputust jututoa uksele. - + You joined this room. Sa liitusid jututoaga. - + %1 has changed their avatar and changed their display name to %2. - + %1 muutis oma tunnuspilti ja seadistas uueks kuvatavaks nimeks %2. %1 has changed their display name to %2. - + %1 seadistas uueks kuvatavaks nimeks %2. @@ -1626,12 +1744,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< %1 lahkus jututoast peale seda, kui ta juba oli lahkunud! - - Reason: %1 - Põhjus: %1 - - - + %1 knocked. %1 müksati välja. @@ -1647,85 +1760,25 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< TimelineView - - Copy - - - - - Copy link location - - - - - React - Reageeri - - - - Reply - Vasta - - - - Edit - Muuda - - - - Read receipts - Lugemisteatised - - - - Forward - - - - - Mark as read - Märgi loetuks - - - - View raw message - Näita sõnumi lähtekoodi - - - - View decrypted raw message - Näita sõnumi dekrüptitud lähtekoodi - - - - Remove message - Eemalda sõnum - - - - Save as - Salvesta kui - - - - Open in external program - Ava välise rakendusega - - - - Copy link to event - - - - + No room open Ühtegi jututuba pole avatud + + + %1 member(s) + %1 liige(t) + + + + Back to room list + Tagasi jututubade loendisse + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Ühtegi krüptitud vestlust selle kasutajaga ei leidunud. Palun loo temaga krüptitud vestlus ja proovi uuesti. @@ -1782,54 +1835,6 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Lõpeta töö - - UserInfoWidget - - - Logout - Logi välja - - - - Set custom status message - Kirjuta kohandatud olekuteade - - - - Custom status message - Kohandatud olekuteade - - - - Status: - Olek: - - - - User Profile Settings - Kasutajaprofiili seadistused - - - - Set presence automatically - Määra oma võrguolek automaatselt - - - - Online - Võrgus - - - - Unavailable - Pole kättesaadav - - - - Offline - Pole võrgus - - UserProfile @@ -1869,7 +1874,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< Võta verifitseerimine tagasi - + Select an avatar Vali tunnuspilt @@ -1892,8 +1897,8 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< UserSettings - - + + Default Vaikimisi @@ -1901,7 +1906,7 @@ testimiseks seni, kuni terviklik seadmete verifitseerimine on implementeeritud.< UserSettingsPage - + Minimize to tray Vähenda tegumiribale @@ -2716,23 +2721,10 @@ Meedia suurus: %2 %1 lõpetas kõne - - popups::UserMentions - - - This Room - See jututuba - - - - All Rooms - Kõik jututoad - - utils - + Unknown Message Type Tundmatu sõnumitüüp diff --git a/resources/langs/nheko_fi.ts b/resources/langs/nheko_fi.ts index d12b1515..9c48e98f 100644 --- a/resources/langs/nheko_fi.ts +++ b/resources/langs/nheko_fi.ts @@ -17,7 +17,7 @@ You are screen sharing - + Olet jakamassa näyttöä @@ -53,30 +53,22 @@ Peruuta - - Cache - - - You joined this room. - - - CallInvite Video Call - + Videopuhelu Voice Call - + Äänipuhelu No microphone found. - + Mikrofonia ei löydy. @@ -84,12 +76,12 @@ Video Call - + Videopuhelu Voice Call - + Äänipuhelu @@ -104,12 +96,12 @@ Unknown microphone: %1 - + Tuntematon mikrofoni: %1 Unknown camera: %1 - + Tuntematon kamera: %1 @@ -119,7 +111,7 @@ No microphone found. - + Mikrofonia ei löydy. @@ -133,30 +125,30 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Kutsuttu käyttäjä: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join - + Vahvista liittyminen Do you really want to join %1? - + Haluatko todella liittyä huoneeseen %1? @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. OLM-tilin palauttaminen epäonnistui. Ole hyvä ja kirjaudu sisään uudelleen. @@ -265,25 +257,25 @@ Tallennettujen tietojen palauttaminen epäonnistui. Ole hyvä ja kirjaudu sisään uudelleen. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Salausavainten lähetys epäonnistui. Palvelimen vastaus: %1 %2. Ole hyvä ja yritä uudelleen myöhemmin. - + Please try to login again: %1 Ole hyvä ja yritä kirjautua sisään uudelleen: %1 Failed to join room: %1 - + Huoneeseen liittyminen epäonnistui: %1 You joined the room - + Sinä liityit huoneeseen @@ -301,55 +293,66 @@ Huoneesta poistuminen epäonnistui: %1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms Kaikki huoneet - - Favourite rooms - Suosikkihuoneet + + Shows all rooms without filtering. + - - Low priority rooms - Alhaisen prioriteetin huoneet - - - - Server Notices - Tag translation for m.server_notice + + Favourites - - (tag) - (tag) + Rooms you have favourited. + - - (community) - (yhteisö) + + Low Priority + + + + + Rooms with low priority. + + + + + Server Notices + + + + + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets @@ -425,22 +428,22 @@ Search - + Hae People - + Ihmiset Nature - + Luonto Food - + Ruoka @@ -450,7 +453,7 @@ Travel - + Matkustaminen @@ -496,7 +499,7 @@ This message is not encrypted! - + Tätä viestiä ei ole salattu! @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Salattu viesti (salauksen purkuavaimia ei löydetty) -- @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -598,13 +601,13 @@ Forward Message - + Välitä viesti InputBar - + Select a file Valitse tiedosto @@ -614,7 +617,7 @@ Kaikki Tiedostot (*) - + Failed to upload media. Please try again. @@ -655,7 +658,7 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th Your password. - + Salasanasi. @@ -670,7 +673,7 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th Homeserver address - + Kotipalvelimen osoite @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. Palvelimen tietojen hakeminen epäonnistui: virheellinen vastaus. @@ -707,7 +710,7 @@ Example: https://server.my:8787 Palvelimen tietojen hakeminen epäonnistui: tuntematon virhe hakiessa .well-known -tiedostoa. - + The required endpoints were not found. Possibly not a Matrix server. Vaadittuja päätepisteitä ei löydetty. Mahdollisesti ei Matrix-palvelin. @@ -722,12 +725,12 @@ Example: https://server.my:8787 Tapahtui tuntematon virhe. Varmista, että kotipalvelimen osoite on pätevä. - + SSO LOGIN - + Empty password Tyhjä salasana @@ -761,12 +764,12 @@ Example: https://server.my:8787 Encryption enabled - + Salaus on käytössä room name changed to: %1 - + huoneen nimi muutettu: %1 @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,23 +868,93 @@ Example: https://server.my:8787 MessageView - + Edit - + Muokkaa React - + Reagoi Reply - + Vastaa Options + Asetukset + + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt @@ -945,7 +1023,7 @@ Example: https://server.my:8787 %1 sent an encrypted message - %1 lähetti salatun viestin + %1 lähetti salatun viestin @@ -957,29 +1035,29 @@ Example: https://server.my:8787 %1 replied: %2 Format a reply in a notification. %1 is the sender, %2 the message - + %1 vastasi: %2 %1: %2 Format a normal message in a notification. %1 is the sender, %2 the message - %1: %2 + %1: %2 %1 replied with an encrypted message - + %1 vastasi salatulla viestillä %1 replied to a message - + %1 vastasi viestiin %1 sent a message - + %1 lähetti viestin @@ -992,7 +1070,7 @@ Example: https://server.my:8787 No microphone found. - + Mikrofonia ei löydy. @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username Käyttäjänimi - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Käyttäjätunnus ei saa olla tyhjä, ja se saa sisältää vain merkkejä a-z, 0-9, ., _, =, - ja /. - + Password Salasana @@ -1072,7 +1150,7 @@ Example: https://server.my:8787 Homeserver - + Kotipalvelin @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER REKISTERÖIDY - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + Palvelimen tietojen hakeminen epäonnistui: virheellinen vastaus. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Palvelimen tietojen hakeminen epäonnistui: tuntematon virhe hakiessa .well-known -tiedostoa. + + + + The required endpoints were not found. Possibly not a Matrix server. + Vaadittuja päätepisteitä ei löydetty. Mahdollisesti ei Matrix-palvelin. + + + + Received malformed response. Make sure the homeserver domain is valid. + Vastaanotettiin virheellinen vastaus. Varmista, että kotipalvelimen osoite on pätevä. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Tapahtui tuntematon virhe. Varmista, että kotipalvelimen osoite on pätevä. + + + Password is not long enough (min 8 chars) Salasana ei ole tarpeeksi pitkä (vähintään 8 merkkiä) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 Salasanat eivät täsmää - + Invalid server name Epäkelpo palvelimen nimi @@ -1113,88 +1216,126 @@ Example: https://server.my:8787 ReplyPopup - + Close Sulje Cancel edit - + Peruuta muokkaus RoomInfo - + no version stored ei tallennettua versiota - RoomInfoListItem + RoomList - - Leave room - Poistu huoneesta - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + Poistu huoneesta + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept Hyväksy - + Decline Hylkää + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Kirjaudu ulos + + + + Start a new chat + Aloita uusi keskustelu + + + + Join a room + Liity huoneeseen + + + + Create a new room + + + + + Room directory + Huoneluettelo + + + + User settings + Käyttäjäasetukset + RoomSettings @@ -1251,12 +1392,12 @@ Example: https://server.my:8787 Encryption - + Salaus End-to-End Encryption - Päästä-päähän-salaus + Päästä-päähän-salaus @@ -1289,43 +1430,43 @@ Example: https://server.my:8787 Room Version - + Huoneen versio OK - OK + OK Failed to enable encryption: %1 - Salauksen aktivointi epäonnistui: %1 + Salauksen aktivointi epäonnistui: %1 Select an avatar - Valitse profiilikuva + Valitse profiilikuva All Files (*) - Kaikki Tiedostot (*) + Kaikki Tiedostot (*) The selected file is not an image - Valittu tiedosto ei ole kuva + Valittu tiedosto ei ole kuva Error while reading file: %1 - Virhe lukiessa tiedostoa: %1 + Virhe lukiessa tiedostoa: %1 Failed to upload image: %s - Kuvan lähetys epäonnistui: %s + Kuvan lähetys epäonnistui: %s @@ -1364,7 +1505,7 @@ Example: https://server.my:8787 Hide mouse cursor - + Piilota hiiren kursori @@ -1379,35 +1520,7 @@ Example: https://server.my:8787 Cancel - Peruuta - - - - SideBarActions - - - User settings - Käyttäjäasetukset - - - - Create new room - Luo uusi huone - - - - Join a room - Liity huoneeseen - - - - Start a new chat - Aloita uusi keskustelu - - - - Room directory - Huoneluettelo + Peruuta @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Viestin muokkaus epäonnistui: %1 @@ -1472,17 +1585,17 @@ Example: https://server.my:8787 Save video - + Tallenna video Save audio - + Tallenna äänitiedosto Save file - + Tallenna tiedosto @@ -1556,7 +1669,7 @@ Example: https://server.my:8787 %1 joined. - + %1 liittyi. @@ -1571,7 +1684,7 @@ Example: https://server.my:8787 %1 left the room. - + %1 poistui huoneesta. @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. - + Sinä liityit tähän huoneeseen. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1635,91 +1748,31 @@ Example: https://server.my:8787 Edited - + Muokattu TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - Lukukuittaukset - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 Lopeta - - UserInfoWidget - - - Logout - Kirjaudu ulos - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar Valitse profiilikuva @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Pienennä ilmoitusalueelle @@ -2148,7 +2153,7 @@ This usually causes the application icon in the task bar to animate in some fash Ringtone - + Soittoääni @@ -2158,12 +2163,12 @@ This usually causes the application icon in the task bar to animate in some fash Microphone - + Mikrofoni Camera - + Kamera @@ -2699,23 +2704,10 @@ Median koko: %2 %1 lopetti puhelun - - popups::UserMentions - - - This Room - Tämä huone - - - - All Rooms - Kaikki huoneet - - utils - + Unknown Message Type Tuntematon viestityyppi diff --git a/resources/langs/nheko_fr.ts b/resources/langs/nheko_fr.ts index 240c8b9f..b6345d62 100644 --- a/resources/langs/nheko_fr.ts +++ b/resources/langs/nheko_fr.ts @@ -53,14 +53,6 @@ Annuler - - Cache - - - You joined this room. - Vous avez rejoint ce salon. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Échec lors de l'invitation de %1 - + Invited user: %1 %1 a été invité(e) - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. La migration du cache vers la version actuelle a échoué. Cela peut arriver pour différentes raisons. Signalez le problème et essayez d'utiliser une ancienne version en attendant. Vous pouvez également supprimer le cache manuellement. - + Confirm join Confirmez la participation @@ -164,13 +156,13 @@ Salon %1 créé. - - + + Confirm invite Confirmer l'invitation - + Do you really want to invite %1 (%2)? Voulez-vous vraiment inviter %1 (%2) ? @@ -235,12 +227,12 @@ %1 n'est plus banni(e) - + Do you really want to start a private chat with %1? Voulez-vous vraimer commencer une discussion privée avec %1 ? - + Cache migration failed! Échec de la migration du cache ! @@ -255,7 +247,7 @@ Le cache sur votre disque est plus récent que cette version de Nheko ne supporte. Veuillez mettre à jour ou supprimer votre cache. - + Failed to restore OLM account. Please login again. Échec de la restauration du compte OLM. Veuillez vous reconnecter. @@ -265,13 +257,13 @@ Échec de la restauration des données sauvegardées. Veuillez vous reconnecter. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Échec de la configuration des clés de chiffrement. Réponse du serveur : %1 %2. Veuillez réessayer plus tard. - + Please try to login again: %1 Veuillez vous reconnecter : %1 @@ -301,55 +293,66 @@ Impossible de quitter le salon : %1 - + Failed to kick %1 from %2: %3 Échec de l'expulsion de %1 depuis %2  : %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community - Cacher les salons portant cette étiquette ou appartenant à cette communauté + + Hide rooms with this tag or from this space by default. + + + + CommunitiesModel - + All rooms - Tous les salons - - - - Favourite rooms - Salons favoris + Tous les salons - Low priority rooms - Salons basse priorité + Shows all rooms without filtering. + + + + + Favourites + + Rooms you have favourited. + + + + + Low Priority + Basse priorité + + + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - Notifications du serveur + Notifications du serveur - - (tag) - (étiquette) - - - - (community) - (communauté) + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets Déchiffrer les secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Évènement chiffré (pas de clé trouvée pour le déchiffrement) -- @@ -529,7 +532,7 @@ -- Événement chiffré (clé invalide pour cet index) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Sélectionnez un fichier @@ -614,7 +617,7 @@ Tous les types de fichiers (*) - + Failed to upload media. Please try again. Échec de l'envoi du média. Veuillez réessayer. @@ -695,13 +698,13 @@ Exemple : https ://monserveur.example.com :8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org Vous avez entré un identifiant Matrix invalide (exemple correct : @moi :mon.serveur.fr) - + Autodiscovery failed. Received malformed response. Échec de la découverte automatique. Réponse mal formatée reçue. @@ -711,7 +714,7 @@ Exemple : https ://monserveur.example.com :8787 Échec de la découverte automatique. Erreur inconnue lors de la demande de .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Les chemins requis n'ont pas été trouvés. Possible qu'il ne s'agisse pas d'un serveur Matrix. @@ -726,12 +729,12 @@ Exemple : https ://monserveur.example.com :8787 Une erreur inconnue est survenue. Vérifiez que le nom de domaine du serveur est valide. - + SSO LOGIN CONNEXION SSO - + Empty password Mot de passe vide @@ -789,6 +792,11 @@ Exemple : https ://monserveur.example.com :8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 a créé et configuré le salon : %2 @@ -864,7 +872,7 @@ Exemple : https ://monserveur.example.com :8787 MessageView - + Edit Modifier @@ -883,6 +891,76 @@ Exemple : https ://monserveur.example.com :8787 Options Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Voir le message brut + + + + View decrypted raw message + Voir le message déchiffré brut + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1022,7 +1100,7 @@ Exemple : https ://monserveur.example.com :8787 Placeholder - + unimplemented event: Évènement non implémenté : @@ -1030,7 +1108,7 @@ Exemple : https ://monserveur.example.com :8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Créer un profil unique, vous permettant de vous connecter simultanément à plusieurs comptes et à lancer plusieurs instances de nheko. @@ -1048,18 +1126,18 @@ Exemple : https ://monserveur.example.com :8787 RegisterPage - + Username Nom d'utilisateur - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Le nom d'utilisateur ne doit pas être vide, et ne peut contenir que les caractères a à z, 0 à 9, et « . _ = - / ». - + Password Mot de passe @@ -1084,22 +1162,47 @@ Exemple : https ://monserveur.example.com :8787 Un serveur qui autorise les créations de compte. Matrix étant décentralisé, vous devez tout d'abord trouver un serveur sur lequel vous pouvez vous inscrire, ou bien héberger le vôtre. - + REGISTER S'ENREGISTRER - + No supported registration flows! Pas de méthode d'inscription supportée ! - + One or more fields have invalid inputs. Please correct those issues and try again. Un ou plusieurs champs ont des entrées invalides. Veuillez les corriger et réessayer. - + + Autodiscovery failed. Received malformed response. + Échec de la découverte automatique. Réponse mal formatée reçue. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Échec de la découverte automatique. Erreur inconnue lors de la demande de .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Les chemins requis n'ont pas été trouvés. Possible qu'il ne s'agisse pas d'un serveur Matrix. + + + + Received malformed response. Make sure the homeserver domain is valid. + Réponse mal formée reçue. Vérifiez que le nom de domaine du serveur est valide. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Une erreur inconnue est survenue. Vérifiez que le nom de domaine du serveur est valide. + + + Password is not long enough (min 8 chars) Le mot de passe n'est pas assez long (8 caractères minimum) @@ -1109,7 +1212,7 @@ Exemple : https ://monserveur.example.com :8787 Les mots de passe ne sont pas identiques - + Invalid server name Le nom du serveur est invalide @@ -1117,7 +1220,7 @@ Exemple : https ://monserveur.example.com :8787 ReplyPopup - + Close Fermer @@ -1130,74 +1233,112 @@ Exemple : https ://monserveur.example.com :8787 RoomInfo - + no version stored pas de version enregistrée - RoomInfoListItem + RoomList - - Leave room - Quitter le salon - - - - Tag room as: - Étiqueter le salon comme : - - - - Favourite - Standard matrix tag for favourites - Favori - - - - Low Priority - Standard matrix tag for low priority rooms - Basse priorité - - - - Server Notice - Standard matrix tag for server notices - Notification du serveur - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Ajoute ou retire l'étiquette spécifiée. - - - - New tag... - Add a new tag to the room - Nouvelle étiquette… - - - - New Tag - Tag name prompt title - Nouvelle étiquette + + New tag + - Tag: - Tag name prompt - Étiquette : + Enter the tag you want to use: + - + + Leave room + Quitter le salon + + + + Tag room as: + Étiqueter le salon comme : + + + + Favourite + Favori + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - Accepter + - + Decline - Décliner + + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Se déconnecter + + + + Start a new chat + Commencer une discussion + + + + Join a room + Rejoindre un salon + + + + Create a new room + + + + + Room directory + Annuaire des salons + + + + User settings + Paramètres utilisateur @@ -1388,34 +1529,6 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Annuler - - SideBarActions - - - User settings - Paramètres utilisateur - - - - Create new room - Créer un nouveau salon - - - - Join a room - Rejoindre un salon - - - - Start a new chat - Commencer une discussion - - - - Room directory - Annuaire des salons - - StatusIndicator @@ -1442,7 +1555,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Success - + Successful Verification Vérification réussie @@ -1460,7 +1573,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineModel - + Message redaction failed: %1 Échec de la suppression du message : %1 @@ -1595,17 +1708,22 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& %1 a été banni. - + + Reason: %1 + + + + %1 redacted their knock. %1 ne frappe plus au salon. - + You joined this room. Vous avez rejoint ce salon. - + %1 has changed their avatar and changed their display name to %2. @@ -1626,12 +1744,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& %1 a quitté le salon après l'avoir déjà quitté ! - - Reason: %1 - Raison : %1 - - - + %1 knocked. %1 a frappé au salon. @@ -1647,85 +1760,25 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& TimelineView - - Copy - - - - - Copy link location - - - - - React - Réagir - - - - Reply - Réponse - - - - Edit - Modifier - - - - Read receipts - Accusés de lecture - - - - Forward - - - - - Mark as read - Marquer comme lu - - - - View raw message - Voir le message brut - - - - View decrypted raw message - Voir le message déchiffré brut - - - - Remove message - Retirer le message - - - - Save as - Enregistrer sous - - - - Open in external program - Ouvrir dans une application externe - - - - Copy link to event - - - - + No room open Aucun salon ouvert + + + %1 member(s) + %1 membre(s) + + + + Back to room list + Revenir à la liste des salons + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Pas de discussion privée et chiffrée trouvée avec cet utilisateur. Créez-en une et réessayez. @@ -1782,54 +1835,6 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Quitter - - UserInfoWidget - - - Logout - Se déconnecter - - - - Set custom status message - Choisir un message de statut personnalisé - - - - Custom status message - Message de statut personnalisé - - - - Status: - Statut : - - - - User Profile Settings - Paramètres du profil utilisateur - - - - Set presence automatically - Changer la présence automatiquement - - - - Online - En ligne - - - - Unavailable - Non disponible - - - - Offline - Hors ligne - - UserProfile @@ -1869,7 +1874,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& Dé-vérifier - + Select an avatar Sélectionner un avatar @@ -1892,8 +1897,8 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& UserSettings - - + + Default Défaut @@ -1901,7 +1906,7 @@ tester le chiffrement de bout en bout tant que la vérification des appareils n& UserSettingsPage - + Minimize to tray Réduire à la barre des tâches @@ -2718,23 +2723,10 @@ Taille du média : %2 %1 a terminé un appel - - popups::UserMentions - - - This Room - Ce salon - - - - All Rooms - Tous les salons - - utils - + Unknown Message Type Type du message inconnu diff --git a/resources/langs/nheko_hu.ts b/resources/langs/nheko_hu.ts index e602929b..e989a6ce 100644 --- a/resources/langs/nheko_hu.ts +++ b/resources/langs/nheko_hu.ts @@ -53,14 +53,6 @@ Mégse - - Cache - - - You joined this room. - Csatlakoztál ehhez a szobához. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Nem sikerült meghívni a felhasználót: %1 - + Invited user: %1 A felhasználó meg lett hívva: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. A gyorsítótár átvitele a jelenlegi verzióhoz nem sikerült. Ennek több oka is lehet. Kérlek, írj egy hibajelentést és egyelőre próbálj meg egy régebbi verziót használni! Alternatív megoldásként megprobálhatod eltávolítani a gyorsítótárat kézzel. - + Confirm join Csatlakozás megerősítése @@ -164,13 +156,13 @@ A %1 nevű szoba létre lett hozva. - - + + Confirm invite Meghívás megerősítése - + Do you really want to invite %1 (%2)? Biztos, hogy meg akarod hívni a következő felhasználót: %1 (%2)? @@ -235,12 +227,12 @@ Kitiltás feloldva a felhasználónak: %1 - + Do you really want to start a private chat with %1? Biztosan privát csevegést akarsz indítani %1 felhasználóval? - + Cache migration failed! Gyorsítótár migráció nem sikerült! @@ -255,7 +247,7 @@ A lemezeden lévő gyorsítótár újabb, mint amit a Nheko jelenlegi verziója támogat. Kérlek, frissítsd vagy töröld a gyorsítótárat! - + Failed to restore OLM account. Please login again. Nem sikerült visszaállítani az OLM fiókot. Kérlek, jelentkezz be ismét! @@ -265,13 +257,13 @@ Nem sikerült visszaállítani a mentési adatot. Kérlek, jelentkezz be ismét! - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Nem sikerült beállítani a titkosítási kulcsokat. Válasz a szervertől: %1 %2. Kérlek, próbáld újra később! - + Please try to login again: %1 Kérlek, próbálj meg bejelentkezni újra: %1 @@ -301,55 +293,66 @@ Nem sikerült elhagyni a szobát: %1 - + Failed to kick %1 from %2: %3 Nem sikerült kirúgni %1 felhasználót %2 szobából: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community - Az ilyen címkével ellátott vagy közösséghez tartozó szobák elrejtése + + Hide rooms with this tag or from this space by default. + + + + CommunitiesModel - + All rooms - Az összes szoba - - - - Favourite rooms - Kedvenc szobák + Az összes szoba - Low priority rooms - Alacsony prioritású szobák + Shows all rooms without filtering. + + + + + Favourites + + Rooms you have favourited. + + + + + Low Priority + Alacsony prioritású + + + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - Szerverértesítések + Szerverértesítések - - (tag) - (címke) - - - - (community) - (közösség) + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets Titkos tároló feloldása @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Titkosított esemény (Nem találhatók kulcsok a titkosítás feloldásához) -- @@ -529,7 +532,7 @@ -- Titkosított esemény (a kulcs nem érvényes ehhez az indexhez) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Fájl kiválasztása @@ -614,7 +617,7 @@ Minden fájl (*) - + Failed to upload media. Please try again. Nem sikerült feltölteni a médiafájlt. Kérlek, próbáld újra! @@ -695,13 +698,13 @@ Példa: https://szerver.em:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org Érvénytelen Matrixazonosítót adtál meg. Példa: @janos:matrix.org - + Autodiscovery failed. Received malformed response. Az automatikus felderítés nem sikerült. Helytelen válasz érkezett. @@ -711,7 +714,7 @@ Példa: https://szerver.em:8787 Az automatikus felderítés nem sikerült. Ismeretlen hiba a .well-known lekérése közben. - + The required endpoints were not found. Possibly not a Matrix server. Nem találhatók szükséges végpontok. Lehet, hogy nem egy Matrixszerver. @@ -726,12 +729,12 @@ Példa: https://szerver.em:8787 Egy ismeretlen hiba történt. Ellenőrizd, hogy a homeszervered domainje helyes. - + SSO LOGIN SSO BEJELENTKEZÉS - + Empty password Üres jelszó @@ -783,6 +786,11 @@ Példa: https://szerver.em:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 létrehozta és beállította a következő szobát: %2 @@ -812,13 +820,13 @@ Példa: https://szerver.em:8787 %1 fogadta a hívást. - + removed eltávolítva - + %1 ended the call. %1 befejezte a hívást. @@ -864,7 +872,7 @@ Példa: https://szerver.em:8787 MessageView - + Edit Szerkesztés @@ -883,6 +891,76 @@ Példa: https://szerver.em:8787 Options Műveletek + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Nyers üzenet megtekintése + + + + View decrypted raw message + Előzőleg titkosított nyers üzenet megtekintése + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1022,7 +1100,7 @@ Példa: https://szerver.em:8787 Placeholder - + unimplemented event: nem implementált esemény: @@ -1030,7 +1108,7 @@ Példa: https://szerver.em:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Egy egyedi profil létrehozása, amellyel be tudsz jelentkezni egyszerre több fiókon keresztül és a Nheko több példányát is tudod futtatni. @@ -1048,18 +1126,18 @@ Példa: https://szerver.em:8787 RegisterPage - + Username Felhasználónév - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. A felhasználónév nem lehet üres és csak a következő karaktereket tartalmazhatja: a-z, 0-9, ., _, =, - és /. - + Password Jelszó @@ -1084,22 +1162,47 @@ Példa: https://szerver.em:8787 Egy szerver, amelyen engedélyezve vannak a regisztrációk. Mivel a Matrix decentralizált, először találnod kell egy szervert, ahol regisztrálhatsz, vagy be kell állítanod a saját szervered. - + REGISTER REGISZTRÁCIÓ - + No supported registration flows! Nem támogatott regisztrációs folyamat! - + One or more fields have invalid inputs. Please correct those issues and try again. Egy vagy több mező tartalma nem helyes. Kérlek, javítsd ki azokat a hibákat, és próbáld újra! - + + Autodiscovery failed. Received malformed response. + Az automatikus felderítés nem sikerült. Helytelen válasz érkezett. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Az automatikus felderítés nem sikerült. Ismeretlen hiba a .well-known lekérése közben. + + + + The required endpoints were not found. Possibly not a Matrix server. + Nem találhatók szükséges végpontok. Lehet, hogy nem egy Matrixszerver. + + + + Received malformed response. Make sure the homeserver domain is valid. + Helytelen válasz érkezett. Ellenőrizd, hogy a homeszervered domainje helyes. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Egy ismeretlen hiba történt. Ellenőrizd, hogy a homeszervered domainje helyes. + + + Password is not long enough (min 8 chars) A jelszó nem elég hosszú (legalább 8 karakter) @@ -1109,7 +1212,7 @@ Példa: https://szerver.em:8787 A jelszavak nem egyeznek - + Invalid server name Nem megfelelő szervernév @@ -1117,7 +1220,7 @@ Példa: https://szerver.em:8787 ReplyPopup - + Close Bezárás @@ -1130,74 +1233,112 @@ Példa: https://szerver.em:8787 RoomInfo - + no version stored nincs tárolva verzió - RoomInfoListItem + RoomList - - Leave room - Szoba elhagyása - - - - Tag room as: - Szoba megcímkézése: - - - - Favourite - Standard matrix tag for favourites - Kedvenc - - - - Low Priority - Standard matrix tag for low priority rooms - Alacsony prioritású - - - - Server Notice - Standard matrix tag for server notices - Szerverértesítés - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Hozzáadja vagy eltávolítja az adott címkét. - - - - New tag... - Add a new tag to the room - Új címke… - - - - New Tag - Tag name prompt title - Új címke + + New tag + - Tag: - Tag name prompt - Címke: + Enter the tag you want to use: + - + + Leave room + Szoba elhagyása + + + + Tag room as: + Szoba megcímkézése: + + + + Favourite + Kedvenc + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - Elfogadás + Elfogadás - + Decline - Elutasítás + Elutasítás + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Kijelentkezés + + + + Start a new chat + Új csevegés indítása + + + + Join a room + Csatlakozás egy szobához + + + + Create a new room + + + + + Room directory + Szobák jegyzéke + + + + User settings + Felhasználói beállítások @@ -1388,34 +1529,6 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Mégse - - SideBarActions - - - User settings - Felhasználói beállítások - - - - Create new room - Új szoba létrehozása - - - - Join a room - Csatlakozás egy szobához - - - - Start a new chat - Új csevegés indítása - - - - Room directory - Szobák jegyzéke - - StatusIndicator @@ -1442,7 +1555,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Success - + Successful Verification Sikeres hitelesítés @@ -1460,7 +1573,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineModel - + Message redaction failed: %1 Az üzenet visszavonása nem sikerült: %1 @@ -1594,17 +1707,22 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh %1 ki lett tiltva. - + + Reason: %1 + + + + %1 redacted their knock. %1 visszavonta a kopogását. - + You joined this room. Csatlakoztál ehhez a szobához. - + %1 has changed their avatar and changed their display name to %2. @@ -1625,12 +1743,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh %1 távozott, miután már egyszer távozott! - - Reason: %1 - Ok: %1 - - - + %1 knocked. %1 kopogott. @@ -1646,85 +1759,25 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh TimelineView - - Copy - - - - - Copy link location - - - - - React - Reakció - - - - Reply - Válasz - - - - Edit - Szerkesztés - - - - Read receipts - Olvasási jegyek - - - - Forward - - - - - Mark as read - Megjelölés olvasottként - - - - View raw message - Nyers üzenet megtekintése - - - - View decrypted raw message - Előzőleg titkosított nyers üzenet megtekintése - - - - Remove message - Üzenet eltávolítása - - - - Save as - Mentés másként - - - - Open in external program - Megnyitás külső programban - - - - Copy link to event - - - - + No room open Nincs nyitott szoba + + + %1 member(s) + %1 tag + + + + Back to room list + Vissza a szobák listájára + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Nem található titkosított privát csevegés ezzel a felhasználóval. Hozz létre egy titkosított privát csevegést vele, és próbáld újra! @@ -1781,54 +1834,6 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Kilépés - - UserInfoWidget - - - Logout - Kijelentkezés - - - - Set custom status message - Egyéni állapotüzenet megadása - - - - Custom status message - Egyéni állapotüzenet - - - - Status: - Állapot: - - - - User Profile Settings - Felhasználói profil beállításai - - - - Set presence automatically - Elérhetőség megadása automatikusan - - - - Online - Bejelentkezve - - - - Unavailable - Nem elérhető - - - - Offline - Kiejelentkezve - - UserProfile @@ -1868,7 +1873,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh Hitelesítés visszavonása - + Select an avatar Profilkép kiválasztása @@ -1891,8 +1896,8 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh UserSettings - - + + Default Alapértelmezett @@ -1900,7 +1905,7 @@ végpontig (E2E) titkosítás tesztelésére, amíg be nincs fejezve az eszközh UserSettingsPage - + Minimize to tray Kicsinyítés a tálcára @@ -2716,23 +2721,10 @@ Média mérete: %2 %1 befejezett egy hívást - - popups::UserMentions - - - This Room - Ez a szoba - - - - All Rooms - Az összes szoba - - utils - + Unknown Message Type Ismeretlen üzenettípus diff --git a/resources/langs/nheko_it.ts b/resources/langs/nheko_it.ts index 7fe04e1b..b0b8ec48 100644 --- a/resources/langs/nheko_it.ts +++ b/resources/langs/nheko_it.ts @@ -6,33 +6,33 @@ Calling... - + Chiamata in corso... Connecting... - + Connessione in corso... You are screen sharing - + Stai condividendo lo schermo Hide/Show Picture-in-Picture - + Nascondi/Mostra Picture-in-Picture Unmute Mic - + Riattiva Microfono Mute Mic - + Silenzia microfono @@ -40,12 +40,12 @@ Awaiting Confirmation - + In attesa di conferma Waiting for other side to complete verification. - + In attesa della conferma dall'altra parte per la verifica. @@ -53,30 +53,22 @@ Annulla - - Cache - - - You joined this room. - Sei entrato in questa stanza. - - CallInvite Video Call - + Chiamata video Voice Call - + Chiamata vocale No microphone found. - + Nessun microfono trovato. @@ -84,22 +76,22 @@ Video Call - + Chiamata Video Voice Call - + Chiamata audio Devices - Dispositivi + Dispositivi Accept - Accetta + Accetta @@ -114,12 +106,12 @@ Decline - Rifiuta + Rifiuta No microphone found. - + Nessun microfono trovato. @@ -127,36 +119,36 @@ Entire screen - + Schermo completo ChatPage - + Failed to invite user: %1 Impossibile invitare l'utente: %1 - + Invited user: %1 Invitato utente: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Migrazione della cache alla versione corrente fallita. Questo può avere diverse cause. Per favore apri una issue e nel frattempo prova ad usare una versione più vecchia. In alternativa puoi provare a cancellare la cache manualmente. - + Confirm join - + Conferma collegamento Do you really want to join %1? - + Vuoi davvero collegarti a %1? @@ -164,15 +156,15 @@ Stanza %1 creata. - - + + Confirm invite - + Conferma Invito - + Do you really want to invite %1 (%2)? - + Vuoi davvero inviare %1 (%2)? @@ -182,12 +174,12 @@ Confirm kick - + Conferma l'allontanamento Do you really want to kick %1 (%2)? - + Vuoi davvero allontanare %1 (%2)? @@ -197,12 +189,12 @@ Confirm ban - + Conferma ban Do you really want to ban %1 (%2)? - + Vuoi veramente bannare %1 (%2)? @@ -217,12 +209,12 @@ Confirm unban - + Conferma reintegro Do you really want to unban %1 (%2)? - + Vuoi veramente reintegrare %1 (%2)? @@ -235,12 +227,12 @@ Rimosso il ban dall'utente: %1 - + Do you really want to start a private chat with %1? - + Sei sicuro di voler avviare una chat privata con %1? - + Cache migration failed! Migrazione della cache fallita! @@ -255,7 +247,7 @@ La cache sul tuo disco è più nuova di quella supportata da questa versione di Nheko. Per favore aggiorna o pulisci la tua cache. - + Failed to restore OLM account. Please login again. Impossibile ripristinare l'account OLM. Per favore accedi nuovamente. @@ -265,13 +257,13 @@ Impossibile ripristinare i dati salvati. Per favore accedi nuovamente. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Impossibile configurare le chiavi crittografiche. Risposta del server: %1 %2. Per favore riprova in seguito. - + Please try to login again: %1 Per favore prova ad accedere nuovamente: %1 @@ -301,77 +293,88 @@ Impossibile lasciare la stanza: %1 - + Failed to kick %1 from %2: %3 + Fallita l'espulsione di %1 da %2: %3 + + + + CommunitiesList + + + Hide rooms with this tag or from this space by default. - CommunitiesListItem + CommunitiesModel - - Hide rooms with this tag or from this community - - - - + All rooms - Tutte le stanze - - - - Favourite rooms - Stanze preferite + Tutte le stanze - Low priority rooms - Stanze a bassa priorità + Shows all rooms without filtering. + - - Server Notices - Tag translation for m.server_notice + + Favourites - - (tag) - (tag) + Rooms you have favourited. + - - (community) - (comunità) + + Low Priority + Tag matrix standard per stanze a bassa priorità + + + + Rooms with low priority. + + + + + Server Notices + Notifiche del server + + + + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets - + Decifra i segreti Enter your recovery key or passphrase to decrypt your secrets: - + Inserisci la chiave di recupero o la parola chiave per decriptare i tuoi segreti: Enter your recovery key or passphrase called %1 to decrypt your secrets: - + Inserisci la tua chiave di recupero o la parola chiave chiamata %1 per decifrare i tuoi segreti: Decryption failed - + Decrittazione fallita Failed to decrypt secrets with the provided recovery key or passphrase - + Fallita la decrittazione usando la chiave di recupero o la parola chiave fornita @@ -379,22 +382,22 @@ Verification Code - + Codice di verifica Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification! - + Verificare i seguenti numeri. Dovresti vedere gli stessi numeri da entrambi i lati. Se differiscono, premi 'Sono diversi!' per annullare la verifica! They do not match! - + Non corrispondono! They match! - + Corrispondono! @@ -425,47 +428,47 @@ Search - + Cerca People - + Membri Nature - + Natura Food - + Cibo Activity - Attività + Attività Travel - + Viaggi Objects - Oggetti + Oggetti Symbols - Simboli + Simboli Flags - Bandiere + Bandiere @@ -473,22 +476,22 @@ Verification Code - + Codice di Verifica Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification! - + Prego verificare le seguenti emoji. Dovresti vedere le stesse emoji su ambo i lati. Se sono diverse, premi 'Non Corrispondono!' per annullare la verifica! They do not match! - + Non corrispondono! They match! - + Corrispondono! @@ -496,57 +499,57 @@ This message is not encrypted! - Questo messaggio è in chiaro! + Questo messaggio non è crittato! Encrypted by a verified device - + Criptato da un dispositivo verificato Encrypted by an unverified device, but you have trusted that user so far. - + Criptato da un dispositivo non verificato ma hai già verificato questo utente. Encrypted by an unverified device - + Criptato da un dispositivo non verificato EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Evento Criptato (Chiavi per la decriptazione non trovate) -- + -- Evento Criptato (Nessuna chiave privata per la decriptazione) -- -- Encrypted Event (Key not valid for this index) -- Placeholder, when the message can't be decrypted with this key since it is not valid for this index - + -- Evento Criptato (Chiave non valida per questo indice) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. - -- Errore di Decrittazione (impossibile recuperare le chiavi megolm dal DB) -- + -- Errore di Decrittazione (impossibile recuperare le chiavi megolm dal DB) -- -- Decryption Error (%1) -- Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed as %1. - -- Errore di Decrittazione (%1) -- + -- Errore di Decrittazione (%1) -- -- Encrypted Event (Unknown event type) -- Placeholder, when the message was decrypted, but we couldn't parse it, because Nheko/mtxclient don't support that event type yet. - -- Evento Criptato (Tipo di evento ignoto) -- + -- Evento Criptato (Tipo di evento ignoto) -- @@ -564,7 +567,7 @@ Verification failed - + Verifica fallita @@ -580,12 +583,12 @@ Device verification timed out. - + Tempo di verifica del dispositivo scaduto. Other party canceled the verification. - + L'altra parte ha annullato la verifica. @@ -598,13 +601,13 @@ Forward Message - + Inoltra Messaggio InputBar - + Select a file Seleziona un file @@ -614,7 +617,7 @@ Tutti i File (*) - + Failed to upload media. Please try again. Impossibile inviare il file multimediale. Per favore riprova. @@ -658,7 +661,7 @@ Se Nheko non conclude la ricerca del tuo homeserver, ti mostrerà un campo in cu Your password. - + La tua password. @@ -673,12 +676,12 @@ Se Nheko non conclude la ricerca del tuo homeserver, ti mostrerà un campo in cu Homeserver address - + Indirizzo Homeserver server.my:8787 - + server.my:8787 @@ -695,13 +698,13 @@ Esempio: https://server.mio:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Hai inserito un ID Matrix non valido, es @joe:matrix.org - + Autodiscovery failed. Received malformed response. Ricerca automatica fallita. Ricevuta risposta malformata. @@ -711,7 +714,7 @@ Esempio: https://server.mio:8787 Ricerca automatica fallita. Errore ignoto durante la richiesta di .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Gli endpoint richiesti non sono stati trovati. Forse non è un server Matrix. @@ -726,12 +729,12 @@ Esempio: https://server.mio:8787 Avvenuto un errore sconosciuto. Assicurati che il dominio dell'homeserver sia valido. - + SSO LOGIN ACCESSO SSO - + Empty password Password vuota @@ -760,7 +763,7 @@ Esempio: https://server.mio:8787 removed - + rimosso @@ -789,13 +792,18 @@ Esempio: https://server.mio:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 creato e configurata stanza: %2 %1 placed a voice call. - + %1 ha avviato una chiamata audio. @@ -810,12 +818,12 @@ Esempio: https://server.mio:8787 %1 answered the call. - + %1 ha risposto alla chiamata. %1 ended the call. - + %1 ha terminato la chiamata. @@ -828,12 +836,12 @@ Esempio: https://server.mio:8787 Hang up - + Termina Place a call - + Avvia una chiamata @@ -853,25 +861,25 @@ Esempio: https://server.mio:8787 Send - + Invia You don't have permission to send messages in this room - + Non hai i permessi per inviare messaggi in questa stanza MessageView - + Edit - + Modifica React - + Reagisci @@ -883,33 +891,104 @@ Esempio: https://server.mio:8787 Options Opzioni + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Mostra il messaggio grezzo + + + + View decrypted raw message + Mostra il messaggio grezzo decriptato + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest Send Verification Request - + Invia richiesta di verifica Received Verification Request - + Richiesta di verifica ricevuta To allow other users to see, which of your devices actually belong to you, you can verify them. This also allows key backup to work automatically. Verify %1 now? - + Per permettere agli altri utenti di vedere che dispositivi ti appartengono, puoi verificarli. Questo inoltre permette alle chiavi di recupero di funzionare automaticamente. +Verificare %1 adesso? To ensure that no malicious user can eavesdrop on your encrypted communications you can verify the other party. - + Per assicurati che nessun malintenzionato intercetti le tue telefonate crittate, puoi verificare l'altra parte. %1 has requested to verify their device %2. - + %1 ha richiesto di verificare il dispositivo %2. @@ -919,7 +998,7 @@ Esempio: https://server.mio:8787 Your device (%1) has requested to be verified. - + Il tuo dispositivo (%1) ha richiesto di essere verificato. @@ -929,12 +1008,12 @@ Esempio: https://server.mio:8787 Deny - + Nega Start verification - + Inizia verifica @@ -955,13 +1034,13 @@ Esempio: https://server.mio:8787 * %1 %2 Format an emote message in a notification, %1 is the sender, %2 the message - + * %1 %2 %1 replied: %2 Format a reply in a notification. %1 is the sender, %2 the message - + Risposta di %1: %2 @@ -973,7 +1052,7 @@ Esempio: https://server.mio:8787 %1 replied with an encrypted message - + %1 ha risposto con un messaggio criptato @@ -996,7 +1075,7 @@ Esempio: https://server.mio:8787 No microphone found. - + Nessun microfono trovato. @@ -1022,15 +1101,15 @@ Esempio: https://server.mio:8787 Placeholder - + unimplemented event: - event non implementato: + evento non implementato: QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1048,18 +1127,18 @@ Esempio: https://server.mio:8787 RegisterPage - + Username Nome utente - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Il nome utente non deve essere vuoto e deve contenere solo i caratteri a-z, 0-9, ., _, =, -, e /. - + Password Password @@ -1084,22 +1163,47 @@ Esempio: https://server.mio:8787 Un server che consente la registrazione. Siccome matrix è decentralizzata, devi prima trovare un server su cui registrarti o ospitarne uno tuo. - + REGISTER REGISTRATI - + No supported registration flows! Non ci sono processi di registrazione supportati! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + Ricerca automatica fallita. Ricevuta risposta malformata. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Ricerca automatica fallita. Errore ignoto durante la richiesta di .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Gli endpoint richiesti non sono stati trovati. Forse non è un server Matrix. + + + + Received malformed response. Make sure the homeserver domain is valid. + Ricevuta risposta malformata. Assicurati che il dominio dell'homeserver sia valido. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Avvenuto un errore sconosciuto. Assicurati che il dominio dell'homeserver sia valido. + + + Password is not long enough (min 8 chars) La password non è abbastanza lunga (minimo 8 caratteri) @@ -1109,7 +1213,7 @@ Esempio: https://server.mio:8787 Le password non corrispondono - + Invalid server name Nome del server non valido @@ -1117,7 +1221,7 @@ Esempio: https://server.mio:8787 ReplyPopup - + Close Chiudi @@ -1130,74 +1234,112 @@ Esempio: https://server.mio:8787 RoomInfo - + no version stored nessuna versione memorizzata - RoomInfoListItem + RoomList - - Leave room - Lascia la stanza - - - - Tag room as: - stanza come: - - - - Favourite - Standard matrix tag for favourites - preferiti - - - - Low Priority - Standard matrix tag for low priority rooms - bassa priorità - - - - Server Notice - Standard matrix tag for server notices - notifiche del server - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Aggiungi o rimuovi il tag specificato. - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - Accetta + + Leave room + Lascia la stanza - + + Tag room as: + stanza come: + + + + Favourite + preferiti + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Accetta + + + Decline - Rifiuta + Rifiuta + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Disconnettiti + + + + Start a new chat + Inizia una nuova discussione + + + + Join a room + Entra in una stanza + + + + Create a new room + + + + + Room directory + Elenco delle stanze + + + + User settings + Impostazioni utente @@ -1386,34 +1528,6 @@ Esempio: https://server.mio:8787 Annulla - - SideBarActions - - - User settings - Impostazioni utente - - - - Create new room - Crea una nuova stanza - - - - Join a room - Entra in una stanza - - - - Start a new chat - Inizia una nuova discussione - - - - Room directory - Elenco delle stanze - - StatusIndicator @@ -1440,7 +1554,7 @@ Esempio: https://server.mio:8787 Success - + Successful Verification @@ -1458,7 +1572,7 @@ Esempio: https://server.mio:8787 TimelineModel - + Message redaction failed: %1 Oscuramento del messaggio fallito: %1 @@ -1520,12 +1634,12 @@ Esempio: https://server.mio:8787 %1 made the room history world readable. Events may be now read by non-joined people. - %1 ha reso la cronologia della stanza leggibile da tutti. Gli eventi adesso possono essere letti da persone esterne. + %1 ha reso la cronologia della stanza leggibile da tutti. Gli eventi adesso possono essere letti da persone esterne. %1 set the room history visible to members from this point on. - %1 ha reso la cronologia della stanza visibile ai membri da questo momento in poi. + %1 ha reso la cronologia della stanza visibile ai membri da questo momento in poi. @@ -1593,17 +1707,22 @@ Esempio: https://server.mio:8787 %1 è stato bannato. - + + Reason: %1 + + + + %1 redacted their knock. %1 ha oscurato la sua bussata. - + You joined this room. Sei entrato in questa stanza. - + %1 has changed their avatar and changed their display name to %2. @@ -1624,12 +1743,7 @@ Esempio: https://server.mio:8787 %1 è uscito dopo essere già uscito! - - Reason: %1 - Motivazione: %1 - - - + %1 knocked. %1 ha bussato. @@ -1645,85 +1759,25 @@ Esempio: https://server.mio:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - Risposta - - - - Edit - - - - - Read receipts - Leggi le ricevute - - - - Forward - - - - - Mark as read - Segna come letto - - - - View raw message - Mostra il messaggio grezzo - - - - View decrypted raw message - Mostra il messaggio grezzo decriptato - - - - Remove message - - - - - Save as - Salva come - - - - Open in external program - - - - - Copy link to event - - - - + No room open Nessuna stanza aperta + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1780,54 +1834,6 @@ Esempio: https://server.mio:8787 Esci - - UserInfoWidget - - - Logout - Disconnettiti - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1867,7 +1873,7 @@ Esempio: https://server.mio:8787 - + Select an avatar Scegli un avatar @@ -1890,8 +1896,8 @@ Esempio: https://server.mio:8787 UserSettings - - + + Default @@ -1899,7 +1905,7 @@ Esempio: https://server.mio:8787 UserSettingsPage - + Minimize to tray Minimizza nella tray @@ -2449,7 +2455,7 @@ This usually causes the application icon in the task bar to animate in some fash Open Fallback in Browser - Apertura di Ripiego nel Browser + Apertura di Ripiego nel Browser @@ -2703,23 +2709,10 @@ Peso media: %2 - - popups::UserMentions - - - This Room - Questa Stanza - - - - All Rooms - Tutte le Stanze - - utils - + Unknown Message Type Tipo di Messaggio sconosciuto diff --git a/resources/langs/nheko_ja.ts b/resources/langs/nheko_ja.ts index 997ffd1a..c7872ce0 100644 --- a/resources/langs/nheko_ja.ts +++ b/resources/langs/nheko_ja.ts @@ -53,14 +53,6 @@ キャンセル - - Cache - - - You joined this room. - - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 ユーザーを招待できませんでした: %1 - + Invited user: %1 招待されたユーザー: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ 永久追放を解除されたユーザー: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. OLMアカウントを復元できませんでした。もう一度ログインして下さい。 @@ -265,13 +257,13 @@ セーブデータを復元できませんでした。もう一度ログインして下さい。 - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. 暗号化鍵を設定できませんでした。サーバーの応答: %1 %2. 後でやり直して下さい。 - + Please try to login again: %1 もう一度ログインしてみて下さい: %1 @@ -301,55 +293,66 @@ 部屋から出られませんでした: %1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - 全ての部屋 - - - - Favourite rooms - お気に入りの部屋 + 全ての部屋 - Low priority rooms - 優先度の低い部屋 + Shows all rooms without filtering. + - - Server Notices - Tag translation for m.server_notice + + Favourites - - (tag) - (タグ) + Rooms you have favourited. + - - (community) - (コミュニティー) + + Low Priority + + + + + Rooms with low priority. + + + + + Server Notices + + + + + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- 暗号化イベント (復号鍵が見つかりません) -- @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file ファイルを選択 @@ -614,7 +617,7 @@ 全てのファイル (*) - + Failed to upload media. Please try again. メディアをアップロードできませんでした。やり直して下さい。 @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. 自動検出できませんでした。不正な形式の応答を受信しました。 @@ -707,7 +710,7 @@ Example: https://server.my:8787 自動検出できませんでした。.well-known要求時の不明なエラー。 - + The required endpoints were not found. Possibly not a Matrix server. 必要な端点が見つかりません。Matrixサーバーではないかもしれません。 @@ -722,12 +725,12 @@ Example: https://server.my:8787 不明なエラーが発生しました。ホームサーバーのドメイン名が有効であるかを確認して下さい。 - + SSO LOGIN - + Empty password パスワードが入力されていません @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options オプション + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + ソースを見る + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: 未実装のイベント: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username ユーザー名 - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password パスワード @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER 登録 - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + 自動検出できませんでした。不正な形式の応答を受信しました。 + + + + Autodiscovery failed. Unknown error when requesting .well-known. + 自動検出できませんでした。.well-known要求時の不明なエラー。 + + + + The required endpoints were not found. Possibly not a Matrix server. + 必要な端点が見つかりません。Matrixサーバーではないかもしれません。 + + + + Received malformed response. Make sure the homeserver domain is valid. + 不正な形式の応答を受信しました。ホームサーバーのドメイン名が有効であるかを確認して下さい。 + + + + An unknown error occured. Make sure the homeserver domain is valid. + 不明なエラーが発生しました。ホームサーバーのドメイン名が有効であるかを確認して下さい。 + + + Password is not long enough (min 8 chars) パスワード長が不足しています (最小8文字) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 パスワードが一致しません - + Invalid server name 無効なサーバー名です @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close 閉じる @@ -1126,74 +1229,112 @@ Example: https://server.my:8787 RoomInfo - + no version stored バージョンが保存されていません - RoomInfoListItem + RoomList - - Leave room - 部屋を出る - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - 容認 + + Leave room + 部屋を出る - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + 容認 + + + Decline - 拒否 + 拒否 + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + ログアウト + + + + Start a new chat + 新しいチャットを開始 + + + + Join a room + 部屋に参加 + + + + Create a new room + + + + + Room directory + 部屋一覧 + + + + User settings + ユーザー設定 @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 キャンセル - - SideBarActions - - - User settings - ユーザー設定 - - - - Create new room - 新しい部屋を作成 - - - - Join a room - 部屋に参加 - - - - Start a new chat - 新しいチャットを開始 - - - - Room directory - 部屋一覧 - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 メッセージを編集できませんでした: %1 @@ -1588,17 +1701,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. %1がノックを編集しました。 - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1619,12 +1737,7 @@ Example: https://server.my:8787 退出済みの%1が退出しました! - - Reason: %1 - - - - + %1 knocked. %1がノックしました。 @@ -1640,85 +1753,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - 返信 - - - - Edit - - - - - Read receipts - 開封確認 - - - - Forward - - - - - Mark as read - 既読にする - - - - View raw message - ソースを見る - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - 名前を付けて保存 - - - - Open in external program - - - - - Copy link to event - - - - + No room open 部屋が開いていません + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1775,54 +1828,6 @@ Example: https://server.my:8787 終了 - - UserInfoWidget - - - Logout - ログアウト - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1862,7 +1867,7 @@ Example: https://server.my:8787 - + Select an avatar アバターを選択 @@ -1885,8 +1890,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1894,7 +1899,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray トレイへ最小化 @@ -2698,23 +2703,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - この部屋 - - - - All Rooms - 全ての部屋 - - utils - + Unknown Message Type 不明なメッセージ型です diff --git a/resources/langs/nheko_ml.ts b/resources/langs/nheko_ml.ts index 79bf26ee..0bdf3b63 100644 --- a/resources/langs/nheko_ml.ts +++ b/resources/langs/nheko_ml.ts @@ -53,14 +53,6 @@ റദ്ദാക്കു - - Cache - - - You joined this room. - നിങ്ങൾ ഈ മുറിയിൽ ചേർന്നു. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 ഉപയോക്താവിനെ ക്ഷണിക്കുന്നതിൽ പരാജയപ്പെട്ടു: %1 - + Invited user: %1 ക്ഷണിച്ച ഉപയോക്താവ്:% 1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ %1 മുറി സൃഷ്ടിച്ചു - - + + Confirm invite ക്ഷണം ഉറപ്പാക്കു - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - എല്ലാ മുറികളും - - - - Favourite rooms - പ്രിയപ്പെട്ട മുറികൾ + എല്ലാ മുറികളും - Low priority rooms - കുറഞ്ഞ മുൻ‌ഗണനയുള്ള മുറികൾ + Shows all rooms without filtering. + + + + + Favourites + + Rooms you have favourited. + + + + + Low Priority + + + + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file ഒരു ഫയൽ തിരഞ്ഞെടുക്കുക @@ -614,7 +617,7 @@ - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password @@ -779,6 +782,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -808,13 +816,13 @@ Example: https://server.my:8787 - + removed നീക്കംചെയ്‌തു - + %1 ended the call. @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password പാസ്‍വേഡ് @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 - + Invalid server name @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close അടയ്‌ക്കുക @@ -1126,75 +1229,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - + Decline നിരസിക്കുക + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + RoomSettings @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 റദ്ദാക്കു - - SideBarActions - - - User settings - - - - - Create new room - - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. നിങ്ങൾ ഈ മുറിയിൽ ചേർന്നു. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2697,23 +2702,10 @@ Media size: %2 %1 ഒരു കോൾ അവസാനിപ്പിച്ചു - - popups::UserMentions - - - This Room - ഈ മുറി - - - - All Rooms - എല്ലാ മുറികളും - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_nl.ts b/resources/langs/nheko_nl.ts index 09270b29..3f2a147f 100644 --- a/resources/langs/nheko_nl.ts +++ b/resources/langs/nheko_nl.ts @@ -53,14 +53,6 @@ Annuleren - - Cache - - - You joined this room. - Je bent lid geworden van deze kamer. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Gebruiker uitnodigen mislukt: %1 - + Invited user: %1 Gebruiker uitgenodigd: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ Kamer %1 gecreëerd. - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Kies een bestand @@ -614,7 +617,7 @@ Alle bestanden (*) - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password Leeg wachtwoord @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username Gebruikersnaam - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password Wachtwoord @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER REGISTREREN - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) Het wachtwoord is niet lang genoeg (minimaal 8 tekens) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 De wachtwoorden komen niet overeen - + Invalid server name Ongeldige servernaam @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,74 +1229,112 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - Kamer verlaten - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - Accepteren + + Leave room + Kamer verlaten - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Accepteren + + + Decline - Afwijzen + Afwijzen + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + Kamer betreden + + + + Create a new room + + + + + Room directory + + + + + User settings + @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 Annuleren - - SideBarActions - - - User settings - - - - - Create new room - Nieuwe kamer creëren - - - - Join a room - Kamer betreden - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. Je bent lid geworden van deze kamer. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - Leesbevestigingen - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 Afsluiten - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Minimaliseren naar systeemvak @@ -2699,23 +2704,10 @@ Mediagrootte: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_pl.ts b/resources/langs/nheko_pl.ts index cc542093..6abcd147 100644 --- a/resources/langs/nheko_pl.ts +++ b/resources/langs/nheko_pl.ts @@ -53,14 +53,6 @@ Anuluj - - Cache - - - You joined this room. - Dołączyłeś(-łaś) do tego pokoju. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Nie udało się zaprosić użytkownika: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? Czy na pewno chcesz zaprosić %1 (%2)? @@ -235,12 +227,12 @@ Odblokowano użytkownika: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Nie udało się przenieść pamięci podręcznej! @@ -255,7 +247,7 @@ Pamięć podręczna na Twoim dysku jest nowsza niż wersja obsługiwana przez Nheko. Zaktualizuj lub wyczyść pamięć podręczną. - + Failed to restore OLM account. Please login again. Nie udało się przywrócić konta OLM. Spróbuj zalogować się ponownie. @@ -265,13 +257,13 @@ Nie udało się przywrócić zapisanych danych. Spróbuj zalogować się ponownie. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Nie udało się ustawić kluczy szyfrujących. Odpowiedź serwera: %1 %2. Spróbuj ponownie później. - + Please try to login again: %1 Spróbuj zalogować się ponownie: %1 @@ -301,55 +293,66 @@ Nie udało się opuścić pokoju: %1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + + + CommunitiesModel + + + All rooms + Wszystkie pokoje + + + + Shows all rooms without filtering. - - All rooms - Wszystkie pokoje - - - - Favourite rooms - Ulubione pokoje + + Favourites + - Low priority rooms - Pokoje o niskim priorytecie + Rooms you have favourited. + + + + + Low Priority + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - Ogłoszenia serwera + Ogłoszenia serwera - - (tag) - (tag) - - - - (community) - (społeczność) + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Zdarzenie szyfrowania (Nie znaleziono kluczy deszyfrujących) @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Wybierz plik @@ -614,7 +617,7 @@ Wszystkie pliki (*) - + Failed to upload media. Please try again. @@ -693,13 +696,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. Automatyczne odkrywanie zakończone niepowodzeniem. Otrzymano nieprawidłową odpowiedź. @@ -709,7 +712,7 @@ Example: https://server.my:8787 Automatyczne odkrywanie zakończone niepowodzeniem. Napotkano nieznany błąd. .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Nie odnaleziono wymaganych punktów końcowych. To może nie być serwer Matriksa. @@ -724,12 +727,12 @@ Example: https://server.my:8787 Wystąpił nieznany błąd. Upewnij się, że domena serwera domowego jest prawidłowa. - + SSO LOGIN Logowanie SSO - + Empty password Puste hasło @@ -787,6 +790,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 utworzył i skonfigurował pokój: %2 @@ -862,7 +870,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -881,6 +889,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1020,7 +1098,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: Niezaimplementowane wydarzenie: @@ -1028,7 +1106,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Stwórz unikalny profil, który pozwoli Ci na zalogowanie się do kilku kont jednocześnie i uruchomienie wielu instancji Nheko. @@ -1046,18 +1124,18 @@ Example: https://server.my:8787 RegisterPage - + Username Nazwa użytkownika - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Nazwa użytkownika nie może być pusta i może zawierać wyłącznie znaki a-z, 0-9, ., _, =, -, i /. - + Password Hasło @@ -1082,22 +1160,47 @@ Example: https://server.my:8787 Serwer, który pozwala na rejestrację. Ponieważ Matrix jest zdecentralizowany, musisz najpierw znaleźć serwer który pozwala na rejestrację bądź hostować swój własny. - + REGISTER ZAREJESTRUJ - + No supported registration flows! Nie wspierana procedura rejestracji! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + Automatyczne odkrywanie zakończone niepowodzeniem. Otrzymano nieprawidłową odpowiedź. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Automatyczne odkrywanie zakończone niepowodzeniem. Napotkano nieznany błąd. .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Nie odnaleziono wymaganych punktów końcowych. To może nie być serwer Matriksa. + + + + Received malformed response. Make sure the homeserver domain is valid. + Otrzymano nieprawidłową odpowiedź. Upewnij się, że domena serwera domowego jest prawidłowa. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Wystąpił nieznany błąd. Upewnij się, że domena serwera domowego jest prawidłowa. + + + Password is not long enough (min 8 chars) Hasło jest zbyt krótkie (min. 8 znaków) @@ -1107,7 +1210,7 @@ Example: https://server.my:8787 Hasła nie pasują do siebie - + Invalid server name Nieprawidłowa nazwa serwera @@ -1115,7 +1218,7 @@ Example: https://server.my:8787 ReplyPopup - + Close Zamknij @@ -1128,74 +1231,112 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - Opuść pokój - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - Akceptuj + + Leave room + Opuść pokój - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Akceptuj + + + Decline - Odrzuć + Odrzuć + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Wyloguj + + + + Start a new chat + Utwórz nowy czat + + + + Join a room + Dołącz do pokoju + + + + Create a new room + + + + + Room directory + Katalog pokojów + + + + User settings + Ustawienia użytkownika @@ -1384,34 +1525,6 @@ Example: https://server.my:8787 Anuluj - - SideBarActions - - - User settings - Ustawienia użytkownika - - - - Create new room - Utwórz nowy pokój - - - - Join a room - Dołącz do pokoju - - - - Start a new chat - Utwórz nowy czat - - - - Room directory - Katalog pokojów - - StatusIndicator @@ -1438,7 +1551,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1456,7 +1569,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Redagowanie wiadomości nie powiodło się: %1 @@ -1592,17 +1705,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. Dołączyłeś(-łaś) do tego pokoju. - + %1 has changed their avatar and changed their display name to %2. @@ -1623,12 +1741,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1644,85 +1757,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - Potwierdzenia przeczytania - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1779,54 +1832,6 @@ Example: https://server.my:8787 Zakończ - - UserInfoWidget - - - Logout - Wyloguj - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1866,7 +1871,7 @@ Example: https://server.my:8787 - + Select an avatar Wybierz awatar @@ -1889,8 +1894,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1898,7 +1903,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray Zminimalizuj do paska zadań @@ -2702,23 +2707,10 @@ Rozmiar multimediów: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_pt_BR.ts b/resources/langs/nheko_pt_BR.ts new file mode 100644 index 00000000..fa0ea193 --- /dev/null +++ b/resources/langs/nheko_pt_BR.ts @@ -0,0 +1,2713 @@ + + + + + ActiveCallBar + + + Calling... + Ligando... + + + + + Connecting... + Conectando... + + + + You are screen sharing + Você está compartilhando sua tela + + + + Hide/Show Picture-in-Picture + Esconder/Mostrar Picture-in-Picture + + + + Unmute Mic + + + + + Mute Mic + + + + + AwaitingVerificationConfirmation + + + Awaiting Confirmation + + + + + Waiting for other side to complete verification. + Esperando o outro lado completar a verificação. + + + + Cancel + Cancelar + + + + CallInvite + + + Video Call + Chamada de Vídeo + + + + Voice Call + Chamada de Voz + + + + No microphone found. + Nenhum microfone encontrado. + + + + CallInviteBar + + + Video Call + Chamada de Vídeo + + + + Voice Call + Chamada de Voz + + + + Devices + Dispositivos + + + + Accept + Aceitar + + + + Unknown microphone: %1 + Microfone desconhecido: %1 + + + + Unknown camera: %1 + Câmera desconhecida: %1 + + + + Decline + Rejeitar + + + + No microphone found. + Nenhum microfone encontrado. + + + + CallManager + + + Entire screen + Tela Inteira + + + + ChatPage + + + Failed to invite user: %1 + Falha ao convidar usuário: %1 + + + + + Invited user: %1 + Usuário convidado: %1 + + + + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. + + + + + Confirm join + Confirmar entrada + + + + Do you really want to join %1? + + + + + Room %1 created. + Sala %1 criada. + + + + + Confirm invite + Confirmar convite + + + + Do you really want to invite %1 (%2)? + + + + + Failed to invite %1 to %2: %3 + Falha ao convidar %1 para %2: %3 + + + + Confirm kick + Confirmar expulsão + + + + Do you really want to kick %1 (%2)? + + + + + Kicked user: %1 + Usuário expulso: %1 + + + + Confirm ban + Confirmar banimento + + + + Do you really want to ban %1 (%2)? + + + + + Failed to ban %1 in %2: %3 + Falha ao banir %1 em %2: %3 + + + + Banned user: %1 + Usuário banido: %1 + + + + Confirm unban + Confirmar desbanimento + + + + Do you really want to unban %1 (%2)? + + + + + Failed to unban %1 in %2: %3 + Falha ao desbanir %1 em %2: %3 + + + + Unbanned user: %1 + Usuário desbanido: %1 + + + + Do you really want to start a private chat with %1? + + + + + Cache migration failed! + Migração do cache falhou! + + + + Incompatible cache version + + + + + The cache on your disk is newer than this version of Nheko supports. Please update or clear your cache. + + + + + Failed to restore OLM account. Please login again. + Falha ao restaurar conta OLM. Por favor faça login novamente. + + + + Failed to restore save data. Please login again. + Falha ao restaurar dados salvos. Por favor faça login novamente. + + + + Failed to setup encryption keys. Server response: %1 %2. Please try again later. + + + + + + Please try to login again: %1 + + + + + Failed to join room: %1 + + + + + You joined the room + + + + + Failed to remove invite: %1 + + + + + Room creation failed: %1 + + + + + Failed to leave room: %1 + + + + + Failed to kick %1 from %2: %3 + + + + + CommunitiesList + + + Hide rooms with this tag or from this space by default. + + + + + CommunitiesModel + + + All rooms + + + + + Shows all rooms without filtering. + + + + + Favourites + + + + + Rooms you have favourited. + + + + + Low Priority + + + + + Rooms with low priority. + + + + + Server Notices + + + + + Messages from your server or administrator. + + + + + CrossSigningSecrets + + + Decrypt secrets + + + + + Enter your recovery key or passphrase to decrypt your secrets: + + + + + Enter your recovery key or passphrase called %1 to decrypt your secrets: + + + + + Decryption failed + + + + + Failed to decrypt secrets with the provided recovery key or passphrase + + + + + DigitVerification + + + Verification Code + + + + + Please verify the following digits. You should see the same numbers on both sides. If they differ, please press 'They do not match!' to abort verification! + + + + + They do not match! + + + + + They match! + + + + + EditModal + + + Apply + + + + + Cancel + Cancelar + + + + Name + + + + + Topic + + + + + EmojiPicker + + + Search + + + + + People + + + + + Nature + + + + + Food + + + + + Activity + + + + + Travel + + + + + Objects + + + + + Symbols + + + + + Flags + + + + + EmojiVerification + + + Verification Code + + + + + Please verify the following emoji. You should see the same emoji on both sides. If they differ, please press 'They do not match!' to abort verification! + + + + + They do not match! + + + + + They match! + + + + + EncryptionIndicator + + + This message is not encrypted! + + + + + Encrypted by a verified device + + + + + Encrypted by an unverified device, but you have trusted that user so far. + + + + + Encrypted by an unverified device + + + + + EventStore + + + -- Encrypted Event (No keys found for decryption) -- + Placeholder, when the message was not decrypted yet or can't be decrypted. + + + + + -- Encrypted Event (Key not valid for this index) -- + Placeholder, when the message can't be decrypted with this key since it is not valid for this index + + + + + + -- Decryption Error (failed to retrieve megolm keys from db) -- + Placeholder, when the message can't be decrypted, because the DB access failed. + + + + + + -- Decryption Error (%1) -- + Placeholder, when the message can't be decrypted. In this case, the Olm decrytion returned an error, which is passed as %1. + + + + + -- Encrypted Event (Unknown event type) -- + Placeholder, when the message was decrypted, but we couldn't parse it, because Nheko/mtxclient don't support that event type yet. + + + + + -- Replay attack! This message index was reused! -- + + + + + -- Message by unverified device! -- + + + + + Failed + + + Verification failed + + + + + Other client does not support our verification protocol. + + + + + Key mismatch detected! + + + + + + Device verification timed out. + + + + + Other party canceled the verification. + + + + + Close + + + + + ForwardCompleter + + + Forward Message + + + + + InputBar + + + Select a file + + + + + All Files (*) + + + + + Failed to upload media. Please try again. + + + + + InviteeItem + + + Remove + + + + + LoginPage + + + Matrix ID + + + + + e.g @joe:matrix.org + + + + + Your login name. A mxid should start with @ followed by the user id. After the user id you need to include your server name after a :. +You can also put your homeserver address there, if your server doesn't support .well-known lookup. +Example: @user:server.my +If Nheko fails to discover your homeserver, it will show you a field to enter the server manually. + + + + + Password + + + + + Your password. + + + + + Device name + + + + + A name for this device, which will be shown to others, when verifying your devices. If none is provided a default is used. + + + + + Homeserver address + + + + + server.my:8787 + + + + + The address that can be used to contact you homeservers client API. +Example: https://server.my:8787 + + + + + LOGIN + + + + + + + + You have entered an invalid Matrix ID e.g @joe:matrix.org + + + + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + + SSO LOGIN + + + + + Empty password + + + + + SSO login failed + + + + + MemberList + + + Room members + + + + + OK + + + + + MessageDelegate + + + Encryption enabled + + + + + room name changed to: %1 + + + + + removed room name + + + + + topic changed to: %1 + + + + + removed topic + + + + + %1 changed the room avatar + + + + + %1 created and configured room: %2 + + + + + %1 placed a voice call. + + + + + %1 placed a video call. + + + + + %1 placed a call. + + + + + Negotiating call... + + + + + %1 answered the call. + + + + + + removed + + + + + %1 ended the call. + + + + + MessageInput + + + Hang up + + + + + Place a call + + + + + Send a file + + + + + Write a message... + + + + + Emoji + + + + + Send + + + + + You don't have permission to send messages in this room + + + + + MessageView + + + Edit + + + + + React + + + + + Reply + + + + + Options + + + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + + + + NewVerificationRequest + + + Send Verification Request + + + + + Received Verification Request + + + + + To allow other users to see, which of your devices actually belong to you, you can verify them. This also allows key backup to work automatically. Verify %1 now? + + + + + To ensure that no malicious user can eavesdrop on your encrypted communications you can verify the other party. + + + + + %1 has requested to verify their device %2. + + + + + %1 using the device %2 has requested to be verified. + + + + + Your device (%1) has requested to be verified. + + + + + Cancel + Cancelar + + + + Deny + + + + + Start verification + + + + + Accept + Aceitar + + + + NotificationsManager + + + + + %1 sent an encrypted message + + + + + * %1 %2 + Format an emote message in a notification, %1 is the sender, %2 the message + + + + + %1 replied: %2 + Format a reply in a notification. %1 is the sender, %2 the message + + + + + %1: %2 + Format a normal message in a notification. %1 is the sender, %2 the message + + + + + + %1 replied with an encrypted message + + + + + %1 replied to a message + + + + + %1 sent a message + + + + + PlaceCall + + + Place a call to %1? + + + + + No microphone found. + Nenhum microfone encontrado. + + + + Voice + + + + + Video + + + + + Screen + + + + + Cancel + Cancelar + + + + Placeholder + + + unimplemented event: + + + + + QCoreApplication + + + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. + + + + + profile + + + + + profile name + + + + + RegisterPage + + + Username + + + + + + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. + + + + + Password + + + + + Please choose a secure password. The exact requirements for password strength may depend on your server. + + + + + Password confirmation + + + + + Homeserver + + + + + A server that allows registration. Since matrix is decentralized, you need to first find a server you can register on or host your own. + + + + + REGISTER + + + + + No supported registration flows! + + + + + One or more fields have invalid inputs. Please correct those issues and try again. + + + + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + + Password is not long enough (min 8 chars) + + + + + Passwords don't match + + + + + Invalid server name + + + + + ReplyPopup + + + Close + + + + + Cancel edit + + + + + RoomInfo + + + no version stored + + + + + RoomList + + + New tag + + + + + Enter the tag you want to use: + + + + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Aceitar + + + + Decline + Rejeitar + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + + + + RoomSettings + + + Room Settings + + + + + %1 member(s) + + + + + SETTINGS + + + + + Notifications + + + + + Muted + + + + + Mentions only + + + + + All messages + + + + + Anyone and guests + + + + + Anyone + + + + + Invited users + + + + + Encryption + + + + + End-to-End Encryption + + + + + Encryption is currently experimental and things might break unexpectedly. <br> + Please take note that it can't be disabled afterwards. + + + + + Respond to key requests + + + + + Whether or not the client should respond automatically with the session keys + upon request. Use with caution, this is a temporary measure to test the + E2E implementation until device verification is completed. + + + + + INFO + + + + + Internal ID + + + + + Room Version + + + + + OK + + + + + Failed to enable encryption: %1 + + + + + Select an avatar + + + + + All Files (*) + + + + + The selected file is not an image + + + + + Error while reading file: %1 + + + + + + Failed to upload image: %s + + + + + ScreenShare + + + Share desktop with %1? + + + + + Window: + + + + + Frame rate: + + + + + Include your camera picture-in-picture + + + + + Request remote camera + + + + + + View your callee's camera like a regular video call + + + + + Hide mouse cursor + + + + + Share + + + + + Preview + + + + + Cancel + Cancelar + + + + StatusIndicator + + + Failed + + + + + Sent + + + + + Received + + + + + Read + + + + + Success + + + Successful Verification + + + + + Verification successful! Both sides verified their devices! + + + + + Close + + + + + TimelineModel + + + Message redaction failed: %1 + + + + + + Failed to encrypt event, sending aborted! + + + + + Save image + + + + + Save video + + + + + Save audio + + + + + Save file + + + + + %1 and %2 are typing. + Multiple users are typing. First argument is a comma separated list of potentially multiple users. Second argument is the last user of that list. (If only one user is typing, %1 is empty. You should still use it in your string though to silence Qt warnings.) + + + + + + + + %1 opened the room to the public. + + + + + %1 made this room require and invitation to join. + + + + + %1 made the room open to guests. + + + + + %1 has closed the room to guest access. + + + + + %1 made the room history world readable. Events may be now read by non-joined people. + + + + + %1 set the room history visible to members from this point on. + + + + + %1 set the room history visible to members since they were invited. + + + + + %1 set the room history visible to members since they joined the room. + + + + + %1 has changed the room's permissions. + + + + + %1 was invited. + + + + + %1 changed their avatar. + + + + + %1 changed some profile info. + + + + + %1 joined. + + + + + %1 rejected their invite. + + + + + Revoked the invite to %1. + + + + + %1 left the room. + + + + + Kicked %1. + + + + + Unbanned %1. + + + + + %1 was banned. + + + + + Reason: %1 + + + + + %1 redacted their knock. + + + + + You joined this room. + Você entrou nessa sala. + + + + %1 has changed their avatar and changed their display name to %2. + + + + + %1 has changed their display name to %2. + + + + + Rejected the knock from %1. + + + + + %1 left after having already left! + This is a leave event after the user already left and shouldn't happen apart from state resets + + + + + %1 knocked. + + + + + TimelineRow + + + Edited + + + + + TimelineView + + + No room open + + + + + %1 member(s) + + + + + Back to room list + + + + + TimelineViewManager + + + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. + + + + + TopBar + + + Back to room list + + + + + + No room selected + + + + + Room options + + + + + Invite users + + + + + Members + + + + + Leave room + + + + + Settings + + + + + TrayIcon + + + Show + + + + + Quit + + + + + UserProfile + + + Global User Profile + + + + + Room User Profile + + + + + + Verify + + + + + Ban the user + + + + + Start a private chat + + + + + Kick the user + + + + + Unverify + + + + + Select an avatar + + + + + All Files (*) + + + + + The selected file is not an image + + + + + Error while reading file: %1 + + + + + UserSettings + + + + Default + + + + + UserSettingsPage + + + Minimize to tray + + + + + Start in tray + + + + + Group's sidebar + + + + + Circular Avatars + + + + + profile: %1 + + + + + Default + + + + + CALLS + + + + + Cross Signing Keys + + + + + REQUEST + + + + + DOWNLOAD + + + + + Keep the application running in the background after closing the client window. + + + + + Start the application in the background without showing the client window. + + + + + Change the appearance of user avatars in chats. +OFF - square, ON - Circle. + + + + + Show a column containing groups and tags next to the room list. + + + + + Decrypt messages in sidebar + + + + + Decrypt the messages shown in the sidebar. +Only affects messages in encrypted chats. + + + + + Privacy Screen + + + + + When the window loses focus, the timeline will +be blurred. + + + + + Privacy screen timeout (in seconds [0 - 3600]) + + + + + Set timeout (in seconds) for how long after window loses +focus before the screen will be blurred. +Set to 0 to blur immediately after focus loss. Max value of 1 hour (3600 seconds) + + + + + Show buttons in timeline + + + + + Show buttons to quickly reply, react or access additional options next to each message. + + + + + Limit width of timeline + + + + + Set the max width of messages in the timeline (in pixels). This can help readability on wide screen, when Nheko is maximised + + + + + Typing notifications + + + + + Show who is typing in a room. +This will also enable or disable sending typing notifications to others. + + + + + Sort rooms by unreads + + + + + Display rooms with new messages first. +If this is off, the list of rooms will only be sorted by the timestamp of the last message in a room. +If this is on, rooms which have active notifications (the small circle with a number in it) will be sorted on top. Rooms, that you have muted, will still be sorted by timestamp, since you don't seem to consider them as important as the other rooms. + + + + + Read receipts + + + + + Show if your message was read. +Status is displayed next to timestamps. + + + + + Send messages as Markdown + + + + + Allow using markdown in messages. +When disabled, all messages are sent as a plain text. + + + + + Desktop notifications + + + + + Notify about received message when the client is not currently focused. + + + + + Alert on notification + + + + + Show an alert when a message is received. +This usually causes the application icon in the task bar to animate in some fashion. + + + + + Highlight message on hover + + + + + Change the background color of messages when you hover over them. + + + + + Large Emoji in timeline + + + + + Make font size larger if messages with only a few emojis are displayed. + + + + + Share keys with verified users and devices + + + + + CACHED + + + + + NOT CACHED + + + + + Scale factor + + + + + Change the scale factor of the whole user interface. + + + + + Font size + + + + + Font Family + + + + + Theme + + + + + Ringtone + + + + + Set the notification sound to play when a call invite arrives + + + + + Microphone + + + + + Camera + + + + + Camera resolution + + + + + Camera frame rate + + + + + Allow fallback call assist server + + + + + Will use turn.matrix.org as assist when your home server does not offer one. + + + + + Device ID + + + + + Device Fingerprint + + + + + Session Keys + + + + + IMPORT + + + + + EXPORT + + + + + ENCRYPTION + + + + + GENERAL + + + + + INTERFACE + + + + + Touchscreen mode + + + + + Will prevent text selection in the timeline to make touch scrolling easier. + + + + + Emoji Font Family + + + + + Automatically replies to key requests from other users, if they are verified. + + + + + Master signing key + + + + + Your most important key. You don't need to have it cached, since not caching it makes it less likely it can be stolen and it is only needed to rotate your other signing keys. + + + + + User signing key + + + + + The key to verify other users. If it is cached, verifying a user will verify all their devices. + + + + + Self signing key + + + + + The key to verify your own devices. If it is cached, verifying one of your devices will mark it verified for all your other devices and for users, that have verified you. + + + + + Backup key + + + + + The key to decrypt online key backups. If it is cached, you can enable online key backup to store encryption keys securely encrypted on the server. + + + + + Select a file + + + + + All Files (*) + + + + + Open Sessions File + + + + + + + + + + Error + + + + + + File Password + + + + + Enter the passphrase to decrypt the file: + + + + + + The password cannot be empty + + + + + Enter passphrase to encrypt your session keys: + + + + + File to save the exported session keys + + + + + Waiting + + + Waiting for other party… + + + + + Waiting for other side to accept the verification request. + + + + + Waiting for other side to continue the verification process. + + + + + Waiting for other side to complete the verification process. + + + + + Cancel + Cancelar + + + + WelcomePage + + + Welcome to nheko! The desktop client for the Matrix protocol. + + + + + Enjoy your stay! + + + + + REGISTER + + + + + LOGIN + + + + + descriptiveTime + + + Yesterday + + + + + dialogs::CreateRoom + + + Create room + + + + + Cancel + Cancelar + + + + Name + + + + + Topic + + + + + Alias + + + + + Room Visibility + + + + + Room Preset + + + + + Direct Chat + + + + + dialogs::FallbackAuth + + + Open Fallback in Browser + + + + + Cancel + Cancelar + + + + Confirm + + + + + Open the fallback, follow the steps and confirm after completing them. + + + + + dialogs::InviteUsers + + + Cancel + Cancelar + + + + User ID to invite + + + + + dialogs::JoinRoom + + + Join + + + + + Cancel + Cancelar + + + + Room ID or alias + + + + + dialogs::LeaveRoom + + + Cancel + Cancelar + + + + Are you sure you want to leave? + + + + + dialogs::Logout + + + Cancel + Cancelar + + + + Logout. Are you sure? + + + + + dialogs::PreviewUploadOverlay + + + Upload + + + + + Cancel + Cancelar + + + + Media type: %1 +Media size: %2 + + + + + + dialogs::ReCaptcha + + + Cancel + Cancelar + + + + Confirm + + + + + Solve the reCAPTCHA and press the confirm button + + + + + dialogs::ReadReceipts + + + Read receipts + + + + + Close + + + + + dialogs::ReceiptItem + + + Today %1 + + + + + Yesterday %1 + + + + + message-description sent: + + + You sent an audio clip + + + + + %1 sent an audio clip + + + + + You sent an image + + + + + %1 sent an image + + + + + You sent a file + + + + + %1 sent a file + + + + + You sent a video + + + + + %1 sent a video + + + + + You sent a sticker + + + + + %1 sent a sticker + + + + + You sent a notification + + + + + %1 sent a notification + + + + + You: %1 + + + + + %1: %2 + + + + + You sent an encrypted message + + + + + %1 sent an encrypted message + + + + + You placed a call + + + + + %1 placed a call + + + + + You answered a call + + + + + %1 answered a call + + + + + You ended a call + + + + + %1 ended a call + + + + + utils + + + Unknown Message Type + + + + diff --git a/resources/langs/nheko_pt_PT.ts b/resources/langs/nheko_pt_PT.ts index 5b041107..81343f97 100644 --- a/resources/langs/nheko_pt_PT.ts +++ b/resources/langs/nheko_pt_PT.ts @@ -53,14 +53,6 @@ - - Cache - - - You joined this room. - - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file @@ -614,7 +617,7 @@ - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password @@ -779,6 +782,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -808,13 +816,13 @@ Example: https://server.my:8787 - + removed - + %1 ended the call. @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 - + Invalid server name @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,75 +1229,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - + Decline + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + RoomSettings @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 - - SideBarActions - - - User settings - - - - - Create new room - - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2697,23 +2702,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_ro.ts b/resources/langs/nheko_ro.ts index 7c35ba42..c21bb069 100644 --- a/resources/langs/nheko_ro.ts +++ b/resources/langs/nheko_ro.ts @@ -53,14 +53,6 @@ - - Cache - - - You joined this room. - Te-ai alăturat camerei. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Nu s-a putut invita utilizatorul: %1 - + Invited user: %1 Utilizator invitat: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Nu s-a putut muta cache-ul pe versiunea curentă. Acest lucru poate avea diferite cauze. Vă rugăm să deschideți un issue și încercați să folosiți o versiune mai veche între timp. O altă opțiune ar fi să încercați să ștergeți cache-ul manual. - + Confirm join @@ -164,13 +156,13 @@ Camera %1 a fost creată. - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ Utilizator dezinterzis: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Nu s-a putut migra cache-ul! @@ -255,7 +247,7 @@ Cache-ul de pe disc este mai nou decât versiunea pe care Nheko o suportă. Vă rugăm actualizați sau ștergeți cache-ul. - + Failed to restore OLM account. Please login again. Nu s-a putut restabili contul OLM. Vă rugăm să vă reconectați. @@ -265,13 +257,13 @@ Nu s-au putut restabili datele salvate. Vă rugăm să vă reconectați. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Nu s-au putut stabili cheile. Răspunsul serverului: %1 %2. Vă rugăm încercați mai târziu. - + Please try to login again: %1 Vă rugăm să vă reconectați: %1 @@ -301,55 +293,66 @@ Nu s-a putut părăsi camera: %1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - Toate camerele - - - - Favourite rooms - Camere favorite + Toate camerele - Low priority rooms - Camere cu prioritate scăzută + Shows all rooms without filtering. + - - Server Notices - Tag translation for m.server_notice + + Favourites - - (tag) - (etichetă) + Rooms you have favourited. + - - (community) - (comunitate) + + Low Priority + + + + + Rooms with low priority. + + + + + Server Notices + + + + + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file @@ -614,7 +617,7 @@ Toate fișierele (*) - + Failed to upload media. Please try again. @@ -695,13 +698,13 @@ Exemplu: https://serverul.meu:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. Autodescoperirea a eșuat. Răspunsul primit este defectuos. @@ -711,7 +714,7 @@ Exemplu: https://serverul.meu:8787 Autodescoperirea a eșuat. Eroare necunoscută la solicitarea .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Punctele finale necesare nu au fost găsite. Posibil a nu fi un server Matrix. @@ -726,12 +729,12 @@ Exemplu: https://serverul.meu:8787 A apărut o eroare necunoscută. Verificați ca domeniul homeserverului să fie valid. - + SSO LOGIN CONECTARE SSO - + Empty password Parolă necompletată @@ -789,6 +792,11 @@ Exemplu: https://serverul.meu:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 a creat și configurat camera: %2 @@ -864,7 +872,7 @@ Exemplu: https://serverul.meu:8787 MessageView - + Edit @@ -883,6 +891,76 @@ Exemplu: https://serverul.meu:8787 Options Opțiuni + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Vedeți mesajul brut + + + + View decrypted raw message + Vedeți mesajul brut decriptat + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1022,7 +1100,7 @@ Exemplu: https://serverul.meu:8787 Placeholder - + unimplemented event: eveniment neimplementat: @@ -1030,7 +1108,7 @@ Exemplu: https://serverul.meu:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1048,18 +1126,18 @@ Exemplu: https://serverul.meu:8787 RegisterPage - + Username Nume de utilizator - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Numele de utilizator nu poate fi gol, și trebuie să conțină doar caracterele a-z, 0-9, ., =, - și /. - + Password Parolă @@ -1084,22 +1162,47 @@ Exemplu: https://serverul.meu:8787 Un server care permite înregistrarea. Deoarece Matrix este decentralizat, trebuie să găsiți un server pe care să vă înregistrați sau să vă găzduiți propriul server. - + REGISTER ÎNREGISTRARE - + No supported registration flows! Fluxuri de înregistrare nesuportate! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + Autodescoperirea a eșuat. Răspunsul primit este defectuos. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Autodescoperirea a eșuat. Eroare necunoscută la solicitarea .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Punctele finale necesare nu au fost găsite. Posibil a nu fi un server Matrix. + + + + Received malformed response. Make sure the homeserver domain is valid. + Răspuns eronat primit. Verificați ca domeniul homeserverului să fie valid. + + + + An unknown error occured. Make sure the homeserver domain is valid. + A apărut o eroare necunoscută. Verificați ca domeniul homeserverului să fie valid. + + + Password is not long enough (min 8 chars) Parola nu este destul de lungă (minim 8 caractere) @@ -1109,7 +1212,7 @@ Exemplu: https://serverul.meu:8787 Parolele nu se potrivesc - + Invalid server name Nume server invalid @@ -1117,7 +1220,7 @@ Exemplu: https://serverul.meu:8787 ReplyPopup - + Close Închide @@ -1130,74 +1233,112 @@ Exemplu: https://serverul.meu:8787 RoomInfo - + no version stored nicio versiune stocată - RoomInfoListItem + RoomList - - Leave room - Părăsește camera - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - Acceptare + + Leave room + Părăsește camera - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + Acceptare + + + Decline - Refuzare + Refuzare + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Deconectare + + + + Start a new chat + Începe o nouă conversație + + + + Join a room + Alătură-te unei camere + + + + Create a new room + + + + + Room directory + Registru de camere + + + + User settings + Setări utilizator @@ -1386,34 +1527,6 @@ Exemplu: https://serverul.meu:8787 - - SideBarActions - - - User settings - Setări utilizator - - - - Create new room - Crează cameră nouă - - - - Join a room - Alătură-te unei camere - - - - Start a new chat - Începe o nouă conversație - - - - Room directory - Registru de camere - - StatusIndicator @@ -1440,7 +1553,7 @@ Exemplu: https://serverul.meu:8787 Success - + Successful Verification @@ -1458,7 +1571,7 @@ Exemplu: https://serverul.meu:8787 TimelineModel - + Message redaction failed: %1 Redactare mesaj eșuată: %1 @@ -1594,17 +1707,22 @@ Exemplu: https://serverul.meu:8787 %1 a fost interzis(ă). - + + Reason: %1 + + + + %1 redacted their knock. %1 și-a redactat ciocănitul. - + You joined this room. Te-ai alăturat camerei. - + %1 has changed their avatar and changed their display name to %2. @@ -1625,12 +1743,7 @@ Exemplu: https://serverul.meu:8787 %1 a părăsit camera după ce a părăsit-o deja înainte! - - Reason: %1 - Motiv: %1 - - - + %1 knocked. %1 a ciocănit. @@ -1646,85 +1759,25 @@ Exemplu: https://serverul.meu:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - Răspuns - - - - Edit - - - - - Read receipts - Confirmări de citire - - - - Forward - - - - - Mark as read - Marcați ca citit - - - - View raw message - Vedeți mesajul brut - - - - View decrypted raw message - Vedeți mesajul brut decriptat - - - - Remove message - - - - - Save as - Salvare ca - - - - Open in external program - - - - - Copy link to event - - - - + No room open Nicio cameră deschisă + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1781,54 +1834,6 @@ Exemplu: https://serverul.meu:8787 Ieșire - - UserInfoWidget - - - Logout - Deconectare - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1868,7 +1873,7 @@ Exemplu: https://serverul.meu:8787 - + Select an avatar Selectează un avatar @@ -1891,8 +1896,8 @@ Exemplu: https://serverul.meu:8787 UserSettings - - + + Default @@ -1900,7 +1905,7 @@ Exemplu: https://serverul.meu:8787 UserSettingsPage - + Minimize to tray Minimizează în bara de notificări @@ -2704,23 +2709,10 @@ Dimensiune media: %2 %1 a încheiat un apel - - popups::UserMentions - - - This Room - Această cameră - - - - All Rooms - Toate camerele - - utils - + Unknown Message Type Tip mesaj necunoscut diff --git a/resources/langs/nheko_ru.ts b/resources/langs/nheko_ru.ts index 3ff6088c..6f2b19af 100644 --- a/resources/langs/nheko_ru.ts +++ b/resources/langs/nheko_ru.ts @@ -17,12 +17,12 @@ You are screen sharing - + Вы демонстрируете экран Hide/Show Picture-in-Picture - + Убрать/Показать Картинку-в-Картинке @@ -53,14 +53,6 @@ Отмена - - Cache - - - You joined this room. - Вы присоединились к этой комнате. - - CallInvite @@ -84,42 +76,42 @@ Video Call - Видео Звонок + Видео Звонок Voice Call - Голосовой Звонок + Голосовой Звонок Devices - Устройства + Устройства Accept - Принять + Принять Unknown microphone: %1 - + Неизвестный микрофон: %1 Unknown camera: %1 - + Неизвестная камера: %1 Decline - Отказаться + Отказаться No microphone found. - Микрофон не найден. + Микрофон не найден. @@ -127,36 +119,36 @@ Entire screen - + Весь экран ChatPage - + Failed to invite user: %1 Не удалось пригласить пользователя: %1 - + Invited user: %1 Приглашенный пользователь: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Миграция кэша для текущей версии не удалась. Это может происходить по разным причинам. Пожалуйста сообщите о проблеме и попробуйте временно использовать старую версию. Так-же вы можете попробовать удалить кэш самостоятельно. - + Confirm join - + Подтвердить вход Do you really want to join %1? - + Вы действительно хотите присоединиться? @@ -164,13 +156,13 @@ Комната %1 создана. - - + + Confirm invite Подтвердите приглашение - + Do you really want to invite %1 (%2)? Вы точно хотите пригласить %1 (%2)? @@ -235,12 +227,12 @@ Разблокированный пользователь: %1 - + Do you really want to start a private chat with %1? - + Вы действительно хотите начать личную переписку с %1? - + Cache migration failed! Миграция кэша не удалась! @@ -255,7 +247,7 @@ Ваш кэш новее, чем эта версия Nheko поддерживает. Пожалуйста обновитесь или отчистите ваш кэш. - + Failed to restore OLM account. Please login again. Не удалось восстановить учетную запись OLM. Пожалуйста, войдите снова. @@ -265,13 +257,13 @@ Не удалось восстановить сохраненные данные. Пожалуйста, войдите снова. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Не удалось настроить ключи шифрования. Ответ сервера:%1 %2. Пожалуйста, попробуйте позже. - + Please try to login again: %1 Повторите попытку входа: %1 @@ -301,77 +293,88 @@ Не удалось покинуть комнату: %1 - + Failed to kick %1 from %2: %3 + Не удалось выгнать %1 из %2: %3 + + + + CommunitiesList + + + Hide rooms with this tag or from this space by default. - CommunitiesListItem + CommunitiesModel - - Hide rooms with this tag or from this community + + All rooms + Все комнаты + + + + Shows all rooms without filtering. - - All rooms - Все комнаты - - - - Favourite rooms - Избранные комнаты + + Favourites + - Low priority rooms - Комнаты с низким приоритетом + Rooms you have favourited. + + + + + Low Priority + Низкий Приоритет + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - Серверные Оповещения + Серверные Оповещения - - (tag) - (тег) - - - - (community) - (сообщество) + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets - + Расшифровать секреты Enter your recovery key or passphrase to decrypt your secrets: - + Введите свой ключ восстановления или пароль для расшифровки секретов: Enter your recovery key or passphrase called %1 to decrypt your secrets: - + Введите свой ключ восстановления или пароль названный %1 для расшифровки Ваших секретов: Decryption failed - + Расшифровка не удалась Failed to decrypt secrets with the provided recovery key or passphrase - + Не удалось расшифровать секреты с помощью предоставленного ключа восстановления или пароля. @@ -501,39 +504,39 @@ Encrypted by a verified device - + Зашифровано верефицированым устройством Encrypted by an unverified device, but you have trusted that user so far. - + Зашифрованно неверефицированым устройством, но Вы все еще доверяете этому пользователю. Encrypted by an unverified device - + Зашифровано неверифицированым устройства EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. - -- Зашифрованное событие (Нет найдено ключей для дешифрования) -- + -- Зашифрованное событие (Не найдено ключей для дешифрования) -- -- Encrypted Event (Key not valid for this index) -- Placeholder, when the message can't be decrypted with this key since it is not valid for this index - + -- Зашифрованное событие(Не найдено ключей для дешифрования) -- - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. - -- Ошибка дешифрования (Не удалось получить megolm-ключи для бд) -- + -- Ошибка дешифрования (Не удалось получить megolm-ключи из бд) -- @@ -598,13 +601,13 @@ Forward Message - + Переслать Сообщение InputBar - + Select a file Выберите файл @@ -614,7 +617,7 @@ Все файлы (*) - + Failed to upload media. Please try again. Не удалось загрузить медиа. Пожалуйста попробуйте ещё раз @@ -658,7 +661,7 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th Your password. - + Ваш пароль. @@ -673,12 +676,12 @@ If Nheko fails to discover your homeserver, it will show you a field to enter th Homeserver address - + Адрес домашнего сервера server.my:8787 - + server.my:8787 @@ -695,13 +698,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Вы ввели не правильный Matrix ID, @joe:matrix.org - + Autodiscovery failed. Received malformed response. Автообноружение не удалось. Получен поврежденный ответ. @@ -711,7 +714,7 @@ Example: https://server.my:8787 Автообноружение не удалось. Не известаня ошибка во время запроса .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Необходимые конечные точки не найдены. Возможно, это не сервер Matrix. @@ -726,12 +729,12 @@ Example: https://server.my:8787 Произошла неизвестная ошибка. Убедитесь, что домен homeserver действителен. - + SSO LOGIN SSO ВХОД - + Empty password Пустой пароль @@ -789,6 +792,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 создал и настроил комнату: %2 @@ -858,30 +866,100 @@ Example: https://server.my:8787 You don't have permission to send messages in this room - + У вас нет прав для отправления сообщений в этой комнате MessageView - + Edit - + Редактировать React - Отреагировать + Реакция Reply - Ответить + Ответить Options - Опции + Опции + + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Просмотреть сырое сообщение + + + + View decrypted raw message + Просмототреть дешифрованое сырое сообщение + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + @@ -889,12 +967,12 @@ Example: https://server.my:8787 Send Verification Request - + Отправить Запрос Верификации Received Verification Request - + Получен Запрос Верификации @@ -949,7 +1027,7 @@ Example: https://server.my:8787 %1 sent an encrypted message - %1 отправил зашифрованное сообщение + %1 отправил зашифрованное сообщение @@ -973,17 +1051,17 @@ Example: https://server.my:8787 %1 replied with an encrypted message - + %1 ответил зашифрованным сообщением %1 replied to a message - + %1 ответил на сообщение %1 sent a message - + %1 отправил сообщениe @@ -991,38 +1069,38 @@ Example: https://server.my:8787 Place a call to %1? - + Позвонить %1? No microphone found. - Микрофон не найден. + Микрофон не найден. Voice - + Голос Video - + Видео Screen - + Экран Cancel - + Отмена Placeholder - + unimplemented event: не реализованное событие @@ -1030,7 +1108,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Создать уникальный профиль, который позволяет вести несколько аккаунтов и запускать множество сущностей nheko. @@ -1048,18 +1126,18 @@ Example: https://server.my:8787 RegisterPage - + Username Имя пользователя - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Имя пользователя не должно быть пустым и должно содержать только символы a-z, 0-9, ., _, =, -, и /. - + Password Пароль @@ -1084,22 +1162,47 @@ Example: https://server.my:8787 Сервер разрешающий регистрацию.Поскольку matrix децентрализованный, нужно выбрать сервер где вы можете зарегистрироваться или поднимите свой сервер. - + REGISTER РЕГИСТРАЦИЯ - + No supported registration flows! Нет поддреживаемых регистрационных потоков - + One or more fields have invalid inputs. Please correct those issues and try again. Одно или более полей имеют некорректный ввод. Пожалуйста устраните ошибки и попробуйте снова. - + + Autodiscovery failed. Received malformed response. + Автообноружение не удалось. Получен поврежденный ответ. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Автообноружение не удалось. Не известаня ошибка во время запроса .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Необходимые конечные точки не найдены. Возможно, это не сервер Matrix. + + + + Received malformed response. Make sure the homeserver domain is valid. + Получен неверный ответ. Убедитесь, что домен homeserver действителен. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Произошла неизвестная ошибка. Убедитесь, что домен homeserver действителен. + + + Password is not long enough (min 8 chars) Слишком короткий пароль (минимум 8 символов) @@ -1109,7 +1212,7 @@ Example: https://server.my:8787 Пароли не совпадают - + Invalid server name Неверное имя сервера @@ -1117,87 +1220,125 @@ Example: https://server.my:8787 ReplyPopup - + Close Закрыть Cancel edit - + Отменить редактирование RoomInfo - + no version stored нет сохраненной версии - RoomInfoListItem + RoomList - - Leave room - Покинуть комнату - - - - Tag room as: - Тэгировать комнату как: - - - - Favourite - Standard matrix tag for favourites - Важные - - - - Low Priority - Standard matrix tag for low priority rooms - Низкий Приоритет - - - - Server Notice - Standard matrix tag for server notices - Серверное Объявление - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Добавить или удалить выбранные тэг. - - - - New tag... - Add a new tag to the room - Добавить новый тег для комнаты - - - - New Tag - Tag name prompt title - Новый Тэг + + New tag + - Tag: - Tag name prompt - Тэг: + Enter the tag you want to use: + - + + Leave room + Покинуть комнату + + + + Tag room as: + Тэгировать комнату как: + + + + Favourite + Важные + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - Принять + Принять - + Decline - Отказаться + Отказаться + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Выйти + + + + Start a new chat + Начать новый чат + + + + Join a room + Присоединиться к комнате + + + + Create a new room + + + + + Room directory + Каталог комнат + + + + User settings + Пользовательские настройки @@ -1205,62 +1346,62 @@ Example: https://server.my:8787 Room Settings - + Настройки комнаты %1 member(s) - + %1 участник(ов) SETTINGS - + НАЙСТРОЙКИ Notifications - + Уведомления Muted - + Заглушен Mentions only - + Упоминания только All messages - + Все сообщения Anyone and guests - + Каждый и гости Anyone - + Каждый Invited users - + Приглашённые пользователи Encryption - + Шифрование End-to-End Encryption - Сквозное шифрование + Оконечное шифрование @@ -1271,7 +1412,7 @@ Example: https://server.my:8787 Respond to key requests - + Отвечать на запрос ключей @@ -1283,53 +1424,53 @@ Example: https://server.my:8787 INFO - + ИНФОРМАЦИЯ Internal ID - + Внутренний ID Room Version - + Версия Комнаты OK - ОК + ОК Failed to enable encryption: %1 - Не удалось включить шифрование: %1 + Не удалось включить шифрование: %1 Select an avatar - Выберите аватар + Выберите аватар All Files (*) - Все файлы (*) + Все файлы (*) The selected file is not an image - Выбранный файл не является картинкой + Выбранный файл не является картинкой Error while reading file: %1 - Ошибка во время прочтения файла: %1 + Ошибка во время прочтения файла: %1 Failed to upload image: %s - Не удалось загрузить изображение: %s + Не удалось загрузить изображение: %s @@ -1337,27 +1478,27 @@ Example: https://server.my:8787 Share desktop with %1? - + Поделиться экраном с %1? Window: - + Окно: Frame rate: - + Частота кадров: Include your camera picture-in-picture - + Включить Вашу камеру в режиме картинка-в-картинке Request remote camera - + Запросить удалённую камеру @@ -1368,50 +1509,22 @@ Example: https://server.my:8787 Hide mouse cursor - + Спрятать курсор мыши Share - + Поделиться Preview - + Предпросмотр Cancel - - - - - SideBarActions - - - User settings - Пользовательские настройки - - - - Create new room - Создать новую комнату - - - - Join a room - Присоединиться к комнате - - - - Start a new chat - Начать новый чат - - - - Room directory - Каталог комнат + Отмена @@ -1440,7 +1553,7 @@ Example: https://server.my:8787 Success - + Successful Verification Верификация прошла успешно @@ -1458,7 +1571,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Ошибка редактирования сообщения: %1 @@ -1594,17 +1707,22 @@ Example: https://server.my:8787 %1 был заблокирован. - + + Reason: %1 + + + + %1 redacted their knock. %1 отредактировал его "стук". - + You joined this room. Вы присоединились к этой комнате. - + %1 has changed their avatar and changed their display name to %2. @@ -1625,12 +1743,7 @@ Example: https://server.my:8787 %1 покинул чат, после того, как уже его покинул. - - Reason: %1 - Причина: %1 - - - + %1 knocked. %1 постучался. @@ -1640,91 +1753,31 @@ Example: https://server.my:8787 Edited - + Изменено TimelineView - - Copy - - - - - Copy link location - - - - - React - Отреагировать - - - - Reply - Ответить - - - - Edit - - - - - Read receipts - Посмотреть получателей - - - - Forward - - - - - Mark as read - Пометить как прочианное - - - - View raw message - Просмотреть сырое сообщение - - - - View decrypted raw message - Просмототреть дешифрованое сырое сообщение - - - - Remove message - Убрать сообщение - - - - Save as - Сохранить как - - - - Open in external program - - - - - Copy link to event - - - - + No room open Комната не выбрана + + + %1 member(s) + %1 участник(ов) + + + + Back to room list + Вернуться к списку комнат + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Не найдено личного чата с этим пользователем. Создайте зашифрованный личный чат с этим пользователем и попытайтесь еще раз. @@ -1781,65 +1834,17 @@ Example: https://server.my:8787 Выйти - - UserInfoWidget - - - Logout - Выйти - - - - Set custom status message - Установить статус - - - - Custom status message - Статус - - - - Status: - Статус: - - - - User Profile Settings - - - - - Set presence automatically - Установить 'presence'автоматически - - - - Online - В сети - - - - Unavailable - Не доступен - - - - Offline - Не в сети - - UserProfile Global User Profile - + Глобальный Пользовательский Профиль Room User Profile - + Поользовательский Профиль в Комнате @@ -1865,42 +1870,42 @@ Example: https://server.my:8787 Unverify - + Отменить Верификацию - + Select an avatar - Выберите аватар + Выберите аватар All Files (*) - Все файлы (*) + Все файлы (*) The selected file is not an image - Выбранный файл не является картинкой + Выбранный файл не является картинкой Error while reading file: %1 - Ошибка во время прочтения файла: %1 + Ошибка во время прочтения файла: %1 UserSettings - - + + Default - + По умолчанию UserSettingsPage - + Minimize to tray Сворачивать в системную панель @@ -1927,7 +1932,7 @@ Example: https://server.my:8787 Default - + По умолчанию @@ -1942,12 +1947,12 @@ Example: https://server.my:8787 REQUEST - + ЗАПРОС DOWNLOAD - + СКАЧАТЬ @@ -1984,7 +1989,7 @@ Only affects messages in encrypted chats. Privacy Screen - + Приватное Окно @@ -2123,12 +2128,12 @@ This usually causes the application icon in the task bar to animate in some fash CACHED - + Закешировано NOT CACHED - + НЕ ЗАКЕШИРОВАНО @@ -2288,7 +2293,7 @@ This usually causes the application icon in the task bar to animate in some fash Backup key - + Ключ восстановления @@ -2710,23 +2715,10 @@ Media size: %2 %1 Закончил разговор - - popups::UserMentions - - - This Room - Эта Комната - - - - All Rooms - Все Комнаты - - utils - + Unknown Message Type Неизвестный Тип Сообщения diff --git a/resources/langs/nheko_si.ts b/resources/langs/nheko_si.ts index c9b094c3..a80adb1b 100644 --- a/resources/langs/nheko_si.ts +++ b/resources/langs/nheko_si.ts @@ -53,14 +53,6 @@ - - Cache - - - You joined this room. - - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 - + Invited user: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. - + Confirm join @@ -164,13 +156,13 @@ - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ - + Do you really want to start a private chat with %1? - + Cache migration failed! @@ -255,7 +247,7 @@ - + Failed to restore OLM account. Please login again. @@ -265,13 +257,13 @@ - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. - + Please try to login again: %1 @@ -301,55 +293,66 @@ - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms + + Shows all rooms without filtering. + + + + + Favourites - Low priority rooms + Rooms you have favourited. + + + + + Low Priority + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file @@ -614,7 +617,7 @@ - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. @@ -722,12 +725,12 @@ Example: https://server.my:8787 - + SSO LOGIN - + Empty password @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + + + + + Received malformed response. Make sure the homeserver domain is valid. + + + + + An unknown error occured. Make sure the homeserver domain is valid. + + + + Password is not long enough (min 8 chars) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 - + Invalid server name @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,75 +1229,113 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - + + Leave room + + + + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - + Decline + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + + + + + Start a new chat + + + + + Join a room + + + + + Create a new room + + + + + Room directory + + + + + User settings + + RoomSettings @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 - - SideBarActions - - - User settings - - - - - Create new room - - - - - Join a room - - - - - Start a new chat - - - - - Room directory - - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 @@ -1589,17 +1702,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. - + %1 has changed their avatar and changed their display name to %2. @@ -1620,12 +1738,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1641,85 +1754,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1776,54 +1829,6 @@ Example: https://server.my:8787 - - UserInfoWidget - - - Logout - - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1863,7 +1868,7 @@ Example: https://server.my:8787 - + Select an avatar @@ -1886,8 +1891,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1895,7 +1900,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray @@ -2697,23 +2702,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/langs/nheko_sv.ts b/resources/langs/nheko_sv.ts index 84410098..8069dcea 100644 --- a/resources/langs/nheko_sv.ts +++ b/resources/langs/nheko_sv.ts @@ -53,14 +53,6 @@ Avbryt - - Cache - - - You joined this room. - Du gick med i detta rum. - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 Kunde inte bjuda in användare: %1 - + Invited user: %1 Bjöd in användare: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. Kunde inte migrera cachen till den nuvarande versionen. Detta kan bero på flera anledningar, vänligen rapportera problemet och prova en äldre version under tiden. Du kan också försöka att manuellt radera cachen. - + Confirm join @@ -164,13 +156,13 @@ Rum %1 skapat. - - + + Confirm invite Bekräfta inbjudan - + Do you really want to invite %1 (%2)? Är du säker på att du vill bjuda in %1 (%2)? @@ -235,12 +227,12 @@ Hävde bannlysningen av användare: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! Cache-migration misslyckades! @@ -255,7 +247,7 @@ Cachen på ditt lagringsmedia är nyare än vad denna version av Nheko stödjer. Vänligen uppdatera eller rensa din cache. - + Failed to restore OLM account. Please login again. Kunde inte återställa OLM-konto. Vänligen logga in på nytt. @@ -265,13 +257,13 @@ Kunde inte återställa sparad data. Vänligen logga in på nytt. - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. Kunde inte sätta upp krypteringsnycklar. Svar från servern: %1 %2. Vänligen försök igen senare. - + Please try to login again: %1 Vänligen försök logga in på nytt: %1 @@ -301,55 +293,66 @@ Kunde inte lämna rum: %1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + + + CommunitiesModel + + + All rooms + Alla rum + + + + Shows all rooms without filtering. - - All rooms - Alla rum - - - - Favourite rooms - Favoritrum + + Favourites + - Low priority rooms - Lågprioritetsrum + Rooms you have favourited. + + + + + Low Priority + Låg prioritet + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - Servernotiser + Servernotiser - - (tag) - (tagg) - - - - (community) - (community) + Messages from your server or administrator. + CrossSigningSecrets - + Decrypt secrets Dekryptera hemliga nycklar @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. -- Krypterat Event (Inga nycklar kunde hittas för dekryptering) -- @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file Välj en fil @@ -614,7 +617,7 @@ Alla Filer (*) - + Failed to upload media. Please try again. Kunde inte ladda upp media. Vänligen försök igen. @@ -695,13 +698,13 @@ Exempel: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. Autouppslag misslyckades. Mottog felkonstruerat svar. @@ -711,7 +714,7 @@ Exempel: https://server.my:8787 Autouppslag misslyckades. Okänt fel uppstod vid begäran av .well-known. - + The required endpoints were not found. Possibly not a Matrix server. Kunde inte hitta de nödvändiga ändpunkterna. Möjligtvis inte en Matrix-server. @@ -726,12 +729,12 @@ Exempel: https://server.my:8787 Ett okänt fel uppstod. Se till att hemserver-domänen är giltig. - + SSO LOGIN SSO INLOGGNING - + Empty password Tomt lösenord @@ -783,6 +786,11 @@ Exempel: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 %1 skapade och konfigurerade rum: %2 @@ -812,13 +820,13 @@ Exempel: https://server.my:8787 %1 besvarade samtalet. - + removed borttagen - + %1 ended the call. %1 avslutade samtalet. @@ -864,7 +872,7 @@ Exempel: https://server.my:8787 MessageView - + Edit @@ -883,6 +891,76 @@ Exempel: https://server.my:8787 Options Alternativ + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + Visa meddelandekälla + + + + View decrypted raw message + Visa dekrypterad meddelandekälla + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1022,7 +1100,7 @@ Exempel: https://server.my:8787 Placeholder - + unimplemented event: ej implementerat event: @@ -1030,7 +1108,7 @@ Exempel: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. Skapa en unik profil, vilket tillåter dig att logga in på flera konton samtidigt och starta flera instanser av Nheko. @@ -1048,18 +1126,18 @@ Exempel: https://server.my:8787 RegisterPage - + Username Användarnamn - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. Användarnamnet kan inte vara tomt, och måste enbart innehålla tecknen a-z, 0-9, ., _, =, -, och /. - + Password Lösenord @@ -1084,22 +1162,47 @@ Exempel: https://server.my:8787 En server som tillåter registrering. Eftersom matrix är decentraliserat behöver du först hitta en server du kan registrera dig på, eller upprätta en på egen hand. - + REGISTER REGISTRERA - + No supported registration flows! Inga stödda registreringsflöden! - + One or more fields have invalid inputs. Please correct those issues and try again. Ett eller flera fält har ogiltigt innehåll. Vänligen korrigera problemen och försök igen. - + + Autodiscovery failed. Received malformed response. + Autouppslag misslyckades. Mottog felkonstruerat svar. + + + + Autodiscovery failed. Unknown error when requesting .well-known. + Autouppslag misslyckades. Okänt fel uppstod vid begäran av .well-known. + + + + The required endpoints were not found. Possibly not a Matrix server. + Kunde inte hitta de nödvändiga ändpunkterna. Möjligtvis inte en Matrix-server. + + + + Received malformed response. Make sure the homeserver domain is valid. + Mottog felkonstruerat svar. Se till att hemserver-domänen är giltig. + + + + An unknown error occured. Make sure the homeserver domain is valid. + Ett okänt fel uppstod. Se till att hemserver-domänen är giltig. + + + Password is not long enough (min 8 chars) Lösenordet är inte långt nog (minst 8 tecken) @@ -1109,7 +1212,7 @@ Exempel: https://server.my:8787 Lösenorden stämmer inte överens - + Invalid server name Ogiltigt servernamn @@ -1117,7 +1220,7 @@ Exempel: https://server.my:8787 ReplyPopup - + Close Stäng @@ -1130,74 +1233,112 @@ Exempel: https://server.my:8787 RoomInfo - + no version stored ingen version lagrad - RoomInfoListItem + RoomList - - Leave room - Lämna rum - - - - Tag room as: - Tagga rum som: - - - - Favourite - Standard matrix tag for favourites - Favorit - - - - Low Priority - Standard matrix tag for low priority rooms - Låg prioritet - - - - Server Notice - Standard matrix tag for server notices - Servernotis - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - Lägger till eller tar bort den angivna taggen. - - - - New tag... - Add a new tag to the room - Ny tagg… - - - - New Tag - Tag name prompt title - Ny tagg + + New tag + - Tag: - Tag name prompt - Tagg: + Enter the tag you want to use: + - + + Leave room + Lämna rum + + + + Tag room as: + Tagga rum som: + + + + Favourite + Favorit + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + Accept - Godkänn + Godkänn - + Decline - Avvisa + + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + Logga ut + + + + Start a new chat + Starta en ny chatt + + + + Join a room + Gå med i ett rum + + + + Create a new room + + + + + Room directory + Rumkatalog + + + + User settings + Användarinställningar @@ -1386,34 +1527,6 @@ Exempel: https://server.my:8787 Avbryt - - SideBarActions - - - User settings - Användarinställningar - - - - Create new room - Skapa nytt rum - - - - Join a room - Gå med i ett rum - - - - Start a new chat - Starta en ny chatt - - - - Room directory - Rumkatalog - - StatusIndicator @@ -1440,7 +1553,7 @@ Exempel: https://server.my:8787 Success - + Successful Verification Lyckad verifikation @@ -1458,7 +1571,7 @@ Exempel: https://server.my:8787 TimelineModel - + Message redaction failed: %1 Kunde inte maskera meddelande: %1 @@ -1593,17 +1706,22 @@ Exempel: https://server.my:8787 %1 blev bannlyst. - + + Reason: %1 + + + + %1 redacted their knock. %1 maskerade sin knackning. - + You joined this room. Du gick med i detta rum. - + %1 has changed their avatar and changed their display name to %2. @@ -1624,12 +1742,7 @@ Exempel: https://server.my:8787 %1 lämnade efter att redan ha lämnat! - - Reason: %1 - Anledning: %1 - - - + %1 knocked. %1 knackade. @@ -1645,85 +1758,25 @@ Exempel: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - Reagera - - - - Reply - Svara - - - - Edit - - - - - Read receipts - Läskvitton - - - - Forward - - - - - Mark as read - Markera som läst - - - - View raw message - Visa meddelandekälla - - - - View decrypted raw message - Visa dekrypterad meddelandekälla - - - - Remove message - Ta bort meddelande - - - - Save as - Spara som - - - - Open in external program - - - - - Copy link to event - - - - + No room open Inget rum öppet + + + %1 member(s) + + + + + Back to room list + Tillbaka till rumlista + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. Ingen krypterad privat chatt med denna användare kunde hittas. Skapa en krypterad privat chatt med användaren och försök igen. @@ -1780,54 +1833,6 @@ Exempel: https://server.my:8787 Avsluta - - UserInfoWidget - - - Logout - Logga ut - - - - Set custom status message - Sätt statusmeddelande - - - - Custom status message - Statusmeddelande - - - - Status: - Status: - - - - User Profile Settings - - - - - Set presence automatically - Sätt närvaro automatiskt - - - - Online - Online - - - - Unavailable - Otillgänglig - - - - Offline - Offline - - UserProfile @@ -1867,7 +1872,7 @@ Exempel: https://server.my:8787 - + Select an avatar Välj en avatar @@ -1890,8 +1895,8 @@ Exempel: https://server.my:8787 UserSettings - - + + Default @@ -1899,7 +1904,7 @@ Exempel: https://server.my:8787 UserSettingsPage - + Minimize to tray Minimera till systemtråg @@ -2711,23 +2716,10 @@ Mediastorlek: %2 %1 lade på - - popups::UserMentions - - - This Room - Detta Rum - - - - All Rooms - Alla Rum - - utils - + Unknown Message Type Okänd meddelandetyp diff --git a/resources/langs/nheko_zh_CN.ts b/resources/langs/nheko_zh_CN.ts index a5d20b67..d468dfaa 100644 --- a/resources/langs/nheko_zh_CN.ts +++ b/resources/langs/nheko_zh_CN.ts @@ -53,14 +53,6 @@ 取消 - - Cache - - - You joined this room. - 您已加入此房间 - - CallInvite @@ -133,23 +125,23 @@ ChatPage - + Failed to invite user: %1 邀请用户失败: %1 - + Invited user: %1 邀请已发送: %1 - + Migrating the cache to the current version failed. This can have different reasons. Please open an issue and try to use an older version in the mean time. Alternatively you can try deleting the cache manually. 无法迁移缓存到目前版本,可能有多种原因引发此类问题。您可以新建一个议题并继续使用之前版本,或者您可以尝试手动删除缓存。 - + Confirm join @@ -164,13 +156,13 @@ 房间“%1”已创建 - - + + Confirm invite - + Do you really want to invite %1 (%2)? @@ -235,12 +227,12 @@ 解禁用户: %1 - + Do you really want to start a private chat with %1? - + Cache migration failed! 缓存迁移失败! @@ -255,7 +247,7 @@ 本地缓存版本比现用的Nheko版本新。请升级Nheko或手动清除缓存。 - + Failed to restore OLM account. Please login again. 恢复 OLM 账户失败。请重新登录。 @@ -265,13 +257,13 @@ 恢复保存的数据失败。请重新登录。 - + Failed to setup encryption keys. Server response: %1 %2. Please try again later. 设置密钥失败。服务器返回信息: %1 %2。请稍后再试。 - + Please try to login again: %1 请尝试再次登录:%1 @@ -301,55 +293,66 @@ 离开聊天室失败:%1 - + Failed to kick %1 from %2: %3 - CommunitiesListItem + CommunitiesList - - Hide rooms with this tag or from this community + + Hide rooms with this tag or from this space by default. + + + CommunitiesModel - + All rooms - - Favourite rooms - 收藏的聊天室 + + Shows all rooms without filtering. + - - Low priority rooms + + Favourites + Rooms you have favourited. + + + + + Low Priority + + + + + Rooms with low priority. + + + + Server Notices - Tag translation for m.server_notice - - (tag) - - - - - (community) + Messages from your server or administrator. CrossSigningSecrets - + Decrypt secrets @@ -517,7 +520,7 @@ EventStore - + -- Encrypted Event (No keys found for decryption) -- Placeholder, when the message was not decrypted yet or can't be decrypted. @@ -529,7 +532,7 @@ - + -- Decryption Error (failed to retrieve megolm keys from db) -- Placeholder, when the message can't be decrypted, because the DB access failed. @@ -604,7 +607,7 @@ InputBar - + Select a file 选择一个文件 @@ -614,7 +617,7 @@ 所有文件(*) - + Failed to upload media. Please try again. @@ -691,13 +694,13 @@ Example: https://server.my:8787 - + You have entered an invalid Matrix ID e.g @joe:matrix.org - + Autodiscovery failed. Received malformed response. @@ -707,7 +710,7 @@ Example: https://server.my:8787 - + The required endpoints were not found. Possibly not a Matrix server. 没找到要求的终端。可能不是一个 Matrix 服务器。 @@ -722,12 +725,12 @@ Example: https://server.my:8787 发生了一个未知错误。请确认服务器域名合法。 - + SSO LOGIN - + Empty password 空密码 @@ -785,6 +788,11 @@ Example: https://server.my:8787 + %1 changed the room avatar + + + + %1 created and configured room: %2 @@ -860,7 +868,7 @@ Example: https://server.my:8787 MessageView - + Edit @@ -879,6 +887,76 @@ Example: https://server.my:8787 Options + + + &Copy + + + + + Copy &link location + + + + + Re&act + + + + + Repl&y + + + + + &Edit + + + + + Read receip&ts + + + + + &Forward + + + + + &Mark as read + + + + + View raw message + + + + + View decrypted raw message + + + + + Remo&ve message + + + + + &Save as + + + + + &Open in external program + + + + + Copy link to eve&nt + + NewVerificationRequest @@ -1018,7 +1096,7 @@ Example: https://server.my:8787 Placeholder - + unimplemented event: @@ -1026,7 +1104,7 @@ Example: https://server.my:8787 QCoreApplication - + Create a unique profile, which allows you to log into several accounts at the same time and start multiple instances of nheko. @@ -1044,18 +1122,18 @@ Example: https://server.my:8787 RegisterPage - + Username 用户名 - + The username must not be empty, and must contain only the characters a-z, 0-9, ., _, =, -, and /. - + Password 密码 @@ -1080,22 +1158,47 @@ Example: https://server.my:8787 - + REGISTER 注册 - + No supported registration flows! - + One or more fields have invalid inputs. Please correct those issues and try again. - + + Autodiscovery failed. Received malformed response. + + + + + Autodiscovery failed. Unknown error when requesting .well-known. + + + + + The required endpoints were not found. Possibly not a Matrix server. + 没找到要求的终端。可能不是一个 Matrix 服务器。 + + + + Received malformed response. Make sure the homeserver domain is valid. + 收到形式错误的响应。请确认服务器域名合法。 + + + + An unknown error occured. Make sure the homeserver domain is valid. + 发生了一个未知错误。请确认服务器域名合法。 + + + Password is not long enough (min 8 chars) 密码不够长(至少8个字符) @@ -1105,7 +1208,7 @@ Example: https://server.my:8787 密码不匹配 - + Invalid server name 无效的服务器名 @@ -1113,7 +1216,7 @@ Example: https://server.my:8787 ReplyPopup - + Close @@ -1126,74 +1229,112 @@ Example: https://server.my:8787 RoomInfo - + no version stored - RoomInfoListItem + RoomList - - Leave room - 离开聊天室 - - - - Tag room as: - - - - - Favourite - Standard matrix tag for favourites - - - - - Low Priority - Standard matrix tag for low priority rooms - - - - - Server Notice - Standard matrix tag for server notices - - - - - Adds or removes the specified tag. - WhatsThis hint for tag menu actions - - - - - New tag... - Add a new tag to the room - - - - - New Tag - Tag name prompt title + + New tag - Tag: - Tag name prompt + Enter the tag you want to use: - - Accept - 接受 + + Leave room + 离开聊天室 - + + Tag room as: + + + + + Favourite + + + + + Low priority + + + + + Server notice + + + + + Create new tag... + + + + + Accept + 接受 + + + Decline - 拒绝 + 拒绝 + + + + Status Message + + + + + Enter your status message: + + + + + Profile settings + + + + + Set status message + + + + + Logout + 登出 + + + + Start a new chat + 开始新的聊天 + + + + Join a room + 加入聊天室 + + + + Create a new room + + + + + Room directory + 聊天室目录 + + + + User settings + 用户设置 @@ -1382,34 +1523,6 @@ Example: https://server.my:8787 取消 - - SideBarActions - - - User settings - 用户设置 - - - - Create new room - 创建新的聊天室 - - - - Join a room - 加入聊天室 - - - - Start a new chat - 开始新的聊天 - - - - Room directory - 聊天室目录 - - StatusIndicator @@ -1436,7 +1549,7 @@ Example: https://server.my:8787 Success - + Successful Verification @@ -1454,7 +1567,7 @@ Example: https://server.my:8787 TimelineModel - + Message redaction failed: %1 删除消息失败:%1 @@ -1588,17 +1701,22 @@ Example: https://server.my:8787 - + + Reason: %1 + + + + %1 redacted their knock. - + You joined this room. 您已加入此房间 - + %1 has changed their avatar and changed their display name to %2. @@ -1619,12 +1737,7 @@ Example: https://server.my:8787 - - Reason: %1 - - - - + %1 knocked. @@ -1640,85 +1753,25 @@ Example: https://server.my:8787 TimelineView - - Copy - - - - - Copy link location - - - - - React - - - - - Reply - - - - - Edit - - - - - Read receipts - 阅读回执 - - - - Forward - - - - - Mark as read - - - - - View raw message - - - - - View decrypted raw message - - - - - Remove message - - - - - Save as - - - - - Open in external program - - - - - Copy link to event - - - - + No room open + + + %1 member(s) + + + + + Back to room list + + TimelineViewManager - + No encrypted private chat found with this user. Create an encrypted private chat with this user and try again. @@ -1775,54 +1828,6 @@ Example: https://server.my:8787 退出 - - UserInfoWidget - - - Logout - 登出 - - - - Set custom status message - - - - - Custom status message - - - - - Status: - - - - - User Profile Settings - - - - - Set presence automatically - - - - - Online - - - - - Unavailable - - - - - Offline - - - UserProfile @@ -1862,7 +1867,7 @@ Example: https://server.my:8787 - + Select an avatar 选择一个头像 @@ -1885,8 +1890,8 @@ Example: https://server.my:8787 UserSettings - - + + Default @@ -1894,7 +1899,7 @@ Example: https://server.my:8787 UserSettingsPage - + Minimize to tray 最小化至托盘 @@ -2698,23 +2703,10 @@ Media size: %2 - - popups::UserMentions - - - This Room - - - - - All Rooms - - - utils - + Unknown Message Type diff --git a/resources/qml/Avatar.qml b/resources/qml/Avatar.qml index 84c22da1..6c12952a 100644 --- a/resources/qml/Avatar.qml +++ b/resources/qml/Avatar.qml @@ -14,6 +14,7 @@ Rectangle { property alias url: img.source property string userid property string displayName + property alias textColor: label.color signal clicked(var mouse) @@ -26,6 +27,8 @@ Rectangle { } Label { + id: label + anchors.fill: parent text: TimelineManager.escapeEmoji(displayName ? String.fromCodePoint(displayName.codePointAt(0)) : "") textFormat: Text.RichText diff --git a/resources/qml/ChatPage.qml b/resources/qml/ChatPage.qml index 0f884d75..7f6758df 100644 --- a/resources/qml/ChatPage.qml +++ b/resources/qml/ChatPage.qml @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import QtQuick 2.9 -import QtQuick.Controls 2.13 +import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import "components" import im.nheko 1.0 @@ -17,19 +17,30 @@ Rectangle { id: adaptiveView anchors.fill: parent - singlePageMode: width < communityListC.maximumWidth + roomListC.maximumWidth + timlineViewC.minimumWidth + singlePageMode: communityListC.preferredWidth + roomListC.preferredWidth + timlineViewC.minimumWidth > width pageIndex: Rooms.currentRoom ? 2 : 1 AdaptiveLayoutElement { id: communityListC - minimumWidth: Nheko.avatarSize * 2 + Nheko.paddingSmall * 2 - collapsedWidth: Nheko.avatarSize + Nheko.paddingSmall * 2 - preferredWidth: Nheko.avatarSize + Nheko.paddingSmall * 2 - maximumWidth: Nheko.avatarSize * 7 + Nheko.paddingSmall * 2 + visible: Settings.groupView + minimumWidth: communitiesList.avatarSize * 4 + Nheko.paddingMedium * 2 + collapsedWidth: communitiesList.avatarSize + 2 * Nheko.paddingMedium + preferredWidth: Settings.communityListWidth >= minimumWidth ? Settings.communityListWidth : collapsedWidth + maximumWidth: communitiesList.avatarSize * 10 + 2 * Nheko.paddingMedium - Rectangle { - color: Nheko.theme.sidebarBackground + CommunitiesList { + id: communitiesList + + collapsed: parent.collapsed + } + + Binding { + target: Settings + property: 'communityListWidth' + value: communityListC.preferredWidth + when: !adaptiveView.singlePageMode + delayed: true } } @@ -37,9 +48,9 @@ Rectangle { AdaptiveLayoutElement { id: roomListC - minimumWidth: Nheko.avatarSize * 5 + Nheko.paddingSmall * 2 - preferredWidth: Nheko.avatarSize * 5 + Nheko.paddingSmall * 2 - maximumWidth: Nheko.avatarSize * 10 + Nheko.paddingSmall * 2 + minimumWidth: roomlist.avatarSize * 4 + Nheko.paddingSmall * 2 + preferredWidth: Settings.roomListWidth >= minimumWidth ? Settings.roomListWidth : roomlist.avatarSize * 5 + Nheko.paddingSmall * 2 + maximumWidth: roomlist.avatarSize * 10 + Nheko.paddingSmall * 2 collapsedWidth: roomlist.avatarSize + 2 * Nheko.paddingMedium RoomList { @@ -48,12 +59,20 @@ Rectangle { collapsed: parent.collapsed } + Binding { + target: Settings + property: 'roomListWidth' + value: roomListC.preferredWidth + when: !adaptiveView.singlePageMode + delayed: true + } + } AdaptiveLayoutElement { id: timlineViewC - minimumWidth: 400 + minimumWidth: fontMetrics.averageCharacterWidth * 40 + Nheko.avatarSize + 2 * Nheko.paddingMedium TimelineView { id: timeline @@ -70,7 +89,7 @@ Rectangle { anchors.fill: parent visible: Settings.privacyScreen screenTimeout: Settings.privacyScreenTimeout - timelineRoot: timeline + timelineRoot: adaptiveView } } diff --git a/resources/qml/CommunitiesList.qml b/resources/qml/CommunitiesList.qml new file mode 100644 index 00000000..491913be --- /dev/null +++ b/resources/qml/CommunitiesList.qml @@ -0,0 +1,160 @@ +// SPDX-FileCopyrightText: 2021 Nheko Contributors +// +// SPDX-License-Identifier: GPL-3.0-or-later + +import "./dialogs" +import Qt.labs.platform 1.1 as Platform +import QtQml 2.12 +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.3 +import im.nheko 1.0 + +Page { + //leftPadding: Nheko.paddingSmall + //rightPadding: Nheko.paddingSmall + property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 1.6) + property bool collapsed: false + + ListView { + id: communitiesList + + anchors.left: parent.left + anchors.right: parent.right + height: parent.height + model: Communities + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + + Platform.Menu { + id: communityContextMenu + + property string tagId + + function show(id_, tags_) { + tagId = id_; + open(); + } + + Platform.MenuItem { + text: qsTr("Hide rooms with this tag or from this space by default.") + onTriggered: Communities.toggleTagId(communityContextMenu.tagId) + } + + } + + delegate: Rectangle { + id: communityItem + + property color background: Nheko.colors.window + property color importantText: Nheko.colors.text + property color unimportantText: Nheko.colors.buttonText + property color bubbleBackground: Nheko.colors.highlight + property color bubbleText: Nheko.colors.highlightedText + + color: background + height: avatarSize + 2 * Nheko.paddingMedium + width: ListView.view.width + state: "normal" + ToolTip.visible: hovered.hovered && collapsed + ToolTip.text: model.tooltip + states: [ + State { + name: "highlight" + when: (hovered.hovered || model.hidden) && !(Communities.currentTagId == model.id) + + PropertyChanges { + target: communityItem + background: Nheko.colors.dark + importantText: Nheko.colors.brightText + unimportantText: Nheko.colors.brightText + bubbleBackground: Nheko.colors.highlight + bubbleText: Nheko.colors.highlightedText + } + + }, + State { + name: "selected" + when: Communities.currentTagId == model.id + + PropertyChanges { + target: communityItem + background: Nheko.colors.highlight + importantText: Nheko.colors.highlightedText + unimportantText: Nheko.colors.highlightedText + bubbleBackground: Nheko.colors.highlightedText + bubbleText: Nheko.colors.highlight + } + + } + ] + + TapHandler { + margin: -Nheko.paddingSmall + acceptedButtons: Qt.RightButton + onSingleTapped: communityContextMenu.show(model.id) + gesturePolicy: TapHandler.ReleaseWithinBounds + } + + TapHandler { + margin: -Nheko.paddingSmall + onSingleTapped: Communities.setCurrentTagId(model.id) + onLongPressed: communityContextMenu.show(model.id) + } + + HoverHandler { + id: hovered + + margin: -Nheko.paddingSmall + } + + RowLayout { + spacing: Nheko.paddingMedium + anchors.fill: parent + anchors.margins: Nheko.paddingMedium + + Avatar { + id: avatar + + enabled: false + Layout.alignment: Qt.AlignVCenter + height: avatarSize + width: avatarSize + url: { + if (model.avatarUrl.startsWith("mxc://")) + return model.avatarUrl.replace("mxc://", "image://MxcImage/"); + else + return "image://colorimage/" + model.avatarUrl + "?" + communityItem.unimportantText; + } + displayName: model.displayName + color: communityItem.background + } + + ElidedLabel { + visible: !collapsed + Layout.alignment: Qt.AlignVCenter + color: communityItem.importantText + elideWidth: parent.width - avatar.width - Nheko.paddingMedium + fullText: model.displayName + textFormat: Text.PlainText + } + + Item { + Layout.fillWidth: true + } + + } + + } + + } + + background: Rectangle { + color: Nheko.theme.sidebarBackground + } + +} diff --git a/resources/qml/ElidedLabel.qml b/resources/qml/ElidedLabel.qml index 1f4aeeea..bc90e479 100644 --- a/resources/qml/ElidedLabel.qml +++ b/resources/qml/ElidedLabel.qml @@ -3,7 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import QtQuick 2.9 -import QtQuick.Controls 2.13 +import QtQuick.Controls 2.5 import im.nheko 1.0 Label { diff --git a/resources/qml/ImageButton.qml b/resources/qml/ImageButton.qml index 60954bfd..b5d9c152 100644 --- a/resources/qml/ImageButton.qml +++ b/resources/qml/ImageButton.qml @@ -26,6 +26,7 @@ AbstractButton { // Workaround, can't get icon.source working for now... anchors.fill: parent source: image != "" ? ("image://colorimage/" + image + "?" + ((button.hovered && changeColorOnHover) ? highlightColor : buttonTextColor)) : "" + fillMode: Image.PreserveAspectFit } CursorShape { diff --git a/resources/qml/MatrixText.qml b/resources/qml/MatrixText.qml index 167899a5..65d66315 100644 --- a/resources/qml/MatrixText.qml +++ b/resources/qml/MatrixText.qml @@ -12,7 +12,8 @@ TextEdit { focus: false wrapMode: Text.Wrap selectByMouse: !Settings.mobileMode - enabled: selectByMouse + // this always has to be enabled, otherwise you can't click links anymore! + //enabled: selectByMouse color: Nheko.colors.text onLinkActivated: Nheko.openLink(link) ToolTip.visible: hoveredLink diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index a3a80b93..16c92ebf 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -449,14 +449,14 @@ ScrollView { Platform.MenuItem { visible: messageContextMenu.text enabled: visible - text: qsTr("Copy") + text: qsTr("&Copy") onTriggered: Clipboard.text = messageContextMenu.text } Platform.MenuItem { visible: messageContextMenu.link enabled: visible - text: qsTr("Copy link location") + text: qsTr("Copy &link location") onTriggered: Clipboard.text = messageContextMenu.link } @@ -464,7 +464,7 @@ ScrollView { id: reactionOption visible: room ? room.permissions.canSend(MtxEvent.Reaction) : false - text: qsTr("React") + text: qsTr("Re&act") onTriggered: emojiPopup.show(null, function(emoji) { room.input.reaction(messageContextMenu.eventId, emoji); }) @@ -472,25 +472,25 @@ ScrollView { Platform.MenuItem { visible: room ? room.permissions.canSend(MtxEvent.TextMessage) : false - text: qsTr("Reply") + text: qsTr("Repl&y") onTriggered: room.replyAction(messageContextMenu.eventId) } Platform.MenuItem { visible: messageContextMenu.isEditable && (room ? room.permissions.canSend(MtxEvent.TextMessage) : false) enabled: visible - text: qsTr("Edit") + text: qsTr("&Edit") onTriggered: room.editAction(messageContextMenu.eventId) } Platform.MenuItem { - text: qsTr("Read receipts") + text: qsTr("Read receip&ts") onTriggered: room.readReceiptsAction(messageContextMenu.eventId) } Platform.MenuItem { visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker || messageContextMenu.eventType == MtxEvent.TextMessage || messageContextMenu.eventType == MtxEvent.LocationMessage || messageContextMenu.eventType == MtxEvent.EmoteMessage || messageContextMenu.eventType == MtxEvent.NoticeMessage - text: qsTr("Forward") + text: qsTr("&Forward") onTriggered: { var forwardMess = forwardCompleterComponent.createObject(timelineRoot); forwardMess.setMessageEventId(messageContextMenu.eventId); @@ -499,7 +499,7 @@ ScrollView { } Platform.MenuItem { - text: qsTr("Mark as read") + text: qsTr("&Mark as read") } Platform.MenuItem { @@ -517,28 +517,28 @@ ScrollView { Platform.MenuItem { visible: (room ? room.permissions.canRedact() : false) || messageContextMenu.isSender - text: qsTr("Remove message") + text: qsTr("Remo&ve message") onTriggered: room.redactEvent(messageContextMenu.eventId) } Platform.MenuItem { visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker enabled: visible - text: qsTr("Save as") + text: qsTr("&Save as") onTriggered: room.saveMedia(messageContextMenu.eventId) } Platform.MenuItem { visible: messageContextMenu.eventType == MtxEvent.ImageMessage || messageContextMenu.eventType == MtxEvent.VideoMessage || messageContextMenu.eventType == MtxEvent.AudioMessage || messageContextMenu.eventType == MtxEvent.FileMessage || messageContextMenu.eventType == MtxEvent.Sticker enabled: visible - text: qsTr("Open in external program") + text: qsTr("&Open in external program") onTriggered: room.openMedia(messageContextMenu.eventId) } Platform.MenuItem { visible: messageContextMenu.eventId enabled: visible - text: qsTr("Copy link to event") + text: qsTr("Copy link to eve&nt") onTriggered: room.copyLinkToEvent(messageContextMenu.eventId) } diff --git a/resources/qml/RoomList.qml b/resources/qml/RoomList.qml index a6637467..c4a8bcfb 100644 --- a/resources/qml/RoomList.qml +++ b/resources/qml/RoomList.qml @@ -4,9 +4,9 @@ import "./dialogs" import Qt.labs.platform 1.1 as Platform -import QtQml 2.13 -import QtQuick 2.13 -import QtQuick.Controls 2.13 +import QtQml 2.12 +import QtQuick 2.12 +import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import im.nheko 1.0 @@ -32,8 +32,8 @@ Page { Connections { onActiveTimelineChanged: { - roomlist.positionViewAtIndex(Rooms.roomidToIndex(TimelineManager.timeline.roomId()), ListView.Contain); - console.log("Test" + TimelineManager.timeline.roomId() + " " + Rooms.roomidToIndex(TimelineManager.timeline.roomId)); + roomlist.positionViewAtIndex(Rooms.roomidToIndex(Rooms.currentRoom.roomId()), ListView.Contain); + console.log("Test" + Rooms.currentRoom.roomId() + " " + Rooms.roomidToIndex(Rooms.currentRoom.roomId())); } target: TimelineManager } @@ -70,7 +70,7 @@ Page { } Instantiator { - model: Communities.tags + model: Communities.tagsWithDefault onObjectAdded: roomContextMenu.insertItem(index + 2, object) onObjectRemoved: roomContextMenu.removeItem(object) @@ -121,7 +121,7 @@ Page { states: [ State { name: "highlight" - when: hovered.hovered && !(TimelineManager.timeline && model.roomId == TimelineManager.timeline.roomId()) + when: hovered.hovered && !(Rooms.currentRoom && model.roomId == Rooms.currentRoom.roomId()) PropertyChanges { target: roomItem @@ -255,6 +255,8 @@ Page { Label { id: timestamp + visible: !model.isInvite && !model.isSpace + width: visible ? 0 : undefined Layout.alignment: Qt.AlignRight | Qt.AlignBottom font.pixelSize: fontMetrics.font.pixelSize * 0.9 color: roomItem.unimportantText @@ -266,12 +268,11 @@ Page { RowLayout { Layout.fillWidth: true spacing: 0 - visible: !model.isInvite + visible: !model.isInvite && !model.isSpace height: visible ? 0 : undefined ElidedLabel { color: roomItem.unimportantText - font.weight: Font.Thin font.pixelSize: fontMetrics.font.pixelSize * 0.9 elideWidth: textContent.width - (notificationBubble.visible ? notificationBubble.width : 0) - Nheko.paddingSmall fullText: model.lastMessage @@ -447,6 +448,8 @@ Page { RowLayout { id: userInfoGrid + property var profile: Nheko.currentUser + spacing: Nheko.paddingMedium anchors.fill: parent anchors.margins: Nheko.paddingMedium @@ -457,9 +460,9 @@ Page { Layout.alignment: Qt.AlignVCenter Layout.preferredWidth: fontMetrics.lineSpacing * 2 Layout.preferredHeight: fontMetrics.lineSpacing * 2 - url: Nheko.currentUser.avatarUrl.replace("mxc://", "image://MxcImage/") - displayName: Nheko.currentUser.displayName - userid: Nheko.currentUser.userid + url: (userInfoGrid.profile ? userInfoGrid.profile.avatarUrl : "").replace("mxc://", "image://MxcImage/") + displayName: userInfoGrid.profile ? userInfoGrid.profile.displayName : "" + userid: userInfoGrid.profile ? userInfoGrid.profile.userid : "" } ColumnLayout { @@ -476,17 +479,16 @@ Page { Layout.alignment: Qt.AlignBottom font.pointSize: fontMetrics.font.pointSize * 1.1 font.weight: Font.DemiBold - fullText: Nheko.currentUser.displayName + fullText: userInfoGrid.profile ? userInfoGrid.profile.displayName : "" elideWidth: col.width } ElidedLabel { Layout.alignment: Qt.AlignTop color: Nheko.colors.buttonText - font.weight: Font.Thin font.pointSize: fontMetrics.font.pointSize * 0.9 elideWidth: col.width - fullText: Nheko.currentUser.userid + fullText: userInfoGrid.profile ? userInfoGrid.profile.userid : "" } } @@ -541,7 +543,7 @@ Page { anchors.margins: Nheko.paddingMedium ImageButton { - Layout.alignment: Qt.AlignBottom | Qt.AlignLeft + Layout.fillWidth: true hoverEnabled: true width: 22 height: 22 @@ -570,7 +572,7 @@ Page { ImageButton { visible: !collapsed - Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter + Layout.fillWidth: true hoverEnabled: true width: 22 height: 22 @@ -582,7 +584,7 @@ Page { ImageButton { visible: !collapsed - Layout.alignment: Qt.AlignBottom | Qt.AlignRight + Layout.fillWidth: true hoverEnabled: true width: 22 height: 22 diff --git a/resources/qml/Root.qml b/resources/qml/Root.qml index 078281d4..5316e20d 100644 --- a/resources/qml/Root.qml +++ b/resources/qml/Root.qml @@ -9,7 +9,7 @@ import "./voip" import Qt.labs.platform 1.1 as Platform import QtGraphicalEffects 1.0 import QtQuick 2.9 -import QtQuick.Controls 2.13 +import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import QtQuick.Window 2.2 import im.nheko 1.0 diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index 5e5eccab..0209054d 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -11,7 +11,7 @@ import "./ui" import Qt.labs.platform 1.1 as Platform import QtGraphicalEffects 1.0 import QtQuick 2.9 -import QtQuick.Controls 2.13 +import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import QtQuick.Window 2.2 import im.nheko 1.0 @@ -44,7 +44,8 @@ Item { ColumnLayout { id: timelineLayout - visible: room != null + visible: room != null && !room.isSpace + enabled: visible anchors.fill: parent spacing: 0 @@ -130,6 +131,79 @@ Item { } + ColumnLayout { + visible: room != null && room.isSpace + enabled: visible + anchors.fill: parent + anchors.margins: Nheko.paddingLarge + spacing: Nheko.paddingLarge + + Avatar { + url: room ? room.roomAvatarUrl.replace("mxc://", "image://MxcImage/") : "" + displayName: room ? room.roomName : "" + height: 130 + width: 130 + Layout.alignment: Qt.AlignHCenter + enabled: false + } + + MatrixText { + text: room ? room.roomName : "" + font.pixelSize: 24 + Layout.alignment: Qt.AlignHCenter + } + + MatrixText { + text: qsTr("%1 member(s)").arg(room ? room.roomMemberCount : 0) + Layout.alignment: Qt.AlignHCenter + } + + ScrollView { + Layout.alignment: Qt.AlignHCenter + width: timelineView.width - Nheko.paddingLarge * 2 + + TextArea { + text: TimelineManager.escapeEmoji(room ? room.roomTopic : "") + wrapMode: TextEdit.WordWrap + textFormat: TextEdit.RichText + readOnly: true + background: null + selectByMouse: true + color: Nheko.colors.text + horizontalAlignment: TextEdit.AlignHCenter + onLinkActivated: Nheko.openLink(link) + + CursorShape { + anchors.fill: parent + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor + } + + } + + } + + Item { + Layout.fillHeight: true + } + + } + + ImageButton { + id: backToRoomsButton + + anchors.top: parent.top + anchors.left: parent.left + anchors.margins: Nheko.paddingMedium + width: Nheko.avatarSize + height: Nheko.avatarSize + visible: room != null && room.isSpace && showBackButton + enabled: visible + image: ":/icons/icons/ui/angle-pointing-to-left.png" + ToolTip.visible: hovered + ToolTip.text: qsTr("Back to room list") + onClicked: Rooms.resetCurrentRoom() + } + NhekoDropArea { anchors.fill: parent roomid: room ? room.roomId() : "" diff --git a/resources/qml/components/AdaptiveLayout.qml b/resources/qml/components/AdaptiveLayout.qml index eea85e38..357a7831 100644 --- a/resources/qml/components/AdaptiveLayout.qml +++ b/resources/qml/components/AdaptiveLayout.qml @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.12 import im.nheko 1.0 Container { @@ -87,6 +87,13 @@ Container { x: parent.preferredWidth z: 3 + CursorShape { + height: parent.height + width: container.splitterGrabMargin * 2 + x: -container.splitterGrabMargin + cursorShape: Qt.SizeHorCursor + } + DragHandler { id: dragHandler @@ -96,9 +103,9 @@ Container { xAxis.minimum: splitter.minimumWidth - 1 xAxis.maximum: splitter.maximumWidth margin: container.splitterGrabMargin - dragThreshold: 0 + //dragThreshold: 0 grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.ApprovesTakeOverByHandlersOfSameType - cursorShape: Qt.SizeHorCursor + //cursorShape: Qt.SizeHorCursor onActiveChanged: { if (!active) splitter.parent.preferredWidth = splitter.x; @@ -107,9 +114,10 @@ Container { } HoverHandler { + //cursorShape: Qt.SizeHorCursor + enabled: !container.singlePageMode margin: container.splitterGrabMargin - cursorShape: Qt.SizeHorCursor } } diff --git a/resources/qml/components/AdaptiveLayoutElement.qml b/resources/qml/components/AdaptiveLayoutElement.qml index 411f6c64..a4aec72e 100644 --- a/resources/qml/components/AdaptiveLayoutElement.qml +++ b/resources/qml/components/AdaptiveLayoutElement.qml @@ -2,9 +2,9 @@ // // SPDX-License-Identifier: GPL-3.0-or-later -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Layouts 1.15 +import QtQuick 2.12 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.12 Item { property int minimumWidth: 100 diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 9e076a7a..1befcec3 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -148,6 +148,15 @@ Item { } + DelegateChoice { + roleValue: MtxEvent.Avatar + + NoticeMessage { + text: qsTr("%1 changed the room avatar").arg(model.data.userName) + } + + } + DelegateChoice { roleValue: MtxEvent.RoomCreate diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index b8c33539..b5090529 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -60,6 +60,7 @@ Item { MessageDelegate { id: reply + enabled: false width: parent.width isReply: true } diff --git a/resources/qml/device-verification/Success.qml b/resources/qml/device-verification/Success.qml index b858a1a1..70cfafaf 100644 --- a/resources/qml/device-verification/Success.qml +++ b/resources/qml/device-verification/Success.qml @@ -5,6 +5,7 @@ import QtQuick 2.3 import QtQuick.Controls 2.3 import QtQuick.Layouts 1.10 +import im.nheko 1.0 Pane { property string title: qsTr("Successful Verification") diff --git a/resources/qml/dialogs/InputDialog.qml b/resources/qml/dialogs/InputDialog.qml index 0cd6be1c..134b78a3 100644 --- a/resources/qml/dialogs/InputDialog.qml +++ b/resources/qml/dialogs/InputDialog.qml @@ -3,8 +3,8 @@ // SPDX-License-Identifier: GPL-3.0-or-later import ".." -import QtQuick 2.13 -import QtQuick.Controls 2.13 +import QtQuick 2.12 +import QtQuick.Controls 2.5 import QtQuick.Layouts 1.3 import im.nheko 1.0 diff --git a/resources/qml/emoji/EmojiPicker.qml b/resources/qml/emoji/EmojiPicker.qml index efcdc2cf..6f10a230 100644 --- a/resources/qml/emoji/EmojiPicker.qml +++ b/resources/qml/emoji/EmojiPicker.qml @@ -35,244 +35,268 @@ Menu { modal: true focus: true closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside - height: columnView.implicitHeight + 4 - width: columnView.implicitWidth + //height: columnView.implicitHeight + 4 + //width: columnView.implicitWidth + width: 7 * 52 + 20 - ColumnLayout { - id: columnView + Rectangle { + color: Nheko.colors.window + height: columnView.implicitHeight + 4 + width: 7 * 52 + 20 - spacing: 0 - anchors.leftMargin: 3 - anchors.rightMargin: 3 - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - anchors.topMargin: 2 + ColumnLayout { + id: columnView - // Search field - TextField { - id: emojiSearch + spacing: 0 + anchors.leftMargin: 3 + anchors.rightMargin: 3 + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.topMargin: 2 - //width: gridView.width - 6 - Layout.topMargin: 3 - Layout.preferredWidth: 7 * 52 + 20 - 6 - placeholderText: qsTr("Search") - selectByMouse: true - rightPadding: clearSearch.width - onTextChanged: searchTimer.restart() - onVisibleChanged: { - if (visible) - forceActiveFocus(); + // Search field + TextField { + id: emojiSearch - } - - Timer { - id: searchTimer - - interval: 350 // tweak as needed? - onTriggered: { - emojiPopup.model.searchString = emojiSearch.text; - emojiPopup.model.category = Emoji.Category.Search; - } - } - - ToolButton { - id: clearSearch - - visible: emojiSearch.text !== '' - icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) - focusPolicy: Qt.NoFocus - onClicked: emojiSearch.clear() - - anchors { - verticalCenter: parent.verticalCenter - right: parent.right - } - // clear the default hover effects. - - background: Item { - } - - } - - } - - // emoji grid - GridView { - id: gridView - - Layout.preferredHeight: cellHeight * 5 - Layout.preferredWidth: 7 * 52 + 20 - Layout.leftMargin: 4 - cellWidth: 52 - cellHeight: 52 - boundsBehavior: Flickable.StopAtBounds - clip: true - currentIndex: -1 // prevent sorting from stealing focus - - // Individual emoji - delegate: AbstractButton { - width: 48 - height: 48 - hoverEnabled: true - ToolTip.text: model.shortName - ToolTip.visible: hovered - // TODO: maybe add favorites at some point? - onClicked: { - console.debug("Picked " + model.unicode); - emojiPopup.close(); - callback(model.unicode); - } - - // give the emoji a little oomf - DropShadow { - width: parent.width - height: parent.height - horizontalOffset: 3 - verticalOffset: 3 - radius: 8 - samples: 17 - color: "#80000000" - source: parent.contentItem - } - - contentItem: Text { - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - font.family: Settings.emojiFont - font.pixelSize: 36 - text: model.unicode - } - - background: Rectangle { - anchors.fill: parent - color: hovered ? Nheko.colors.highlight : 'transparent' - radius: 5 - } - - } - - ScrollBar.vertical: ScrollBar { - id: emojiScroll - } - - } - - // Separator - Rectangle { - visible: emojiSearch.text === '' - Layout.fillWidth: true - Layout.preferredHeight: 1 - color: emojiPopup.Nheko.colors.alternateBase - } - - // Category picker row - RowLayout { - visible: emojiSearch.text === '' - Layout.bottomMargin: 0 - Layout.preferredHeight: 42 - implicitHeight: 42 - Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom - - // Display the normal categories - Repeater { - - model: ListModel { - // TODO: Would like to get 'simple' icons for the categories - ListElement { - image: ":/icons/icons/emoji-categories/people.png" - category: Emoji.Category.People - } - - ListElement { - image: ":/icons/icons/emoji-categories/nature.png" - category: Emoji.Category.Nature - } - - ListElement { - image: ":/icons/icons/emoji-categories/foods.png" - category: Emoji.Category.Food - } - - ListElement { - image: ":/icons/icons/emoji-categories/activity.png" - category: Emoji.Category.Activity - } - - ListElement { - image: ":/icons/icons/emoji-categories/travel.png" - category: Emoji.Category.Travel - } - - ListElement { - image: ":/icons/icons/emoji-categories/objects.png" - category: Emoji.Category.Objects - } - - ListElement { - image: ":/icons/icons/emoji-categories/symbols.png" - category: Emoji.Category.Symbols - } - - ListElement { - image: ":/icons/icons/emoji-categories/flags.png" - category: Emoji.Category.Flags - } + Layout.topMargin: 3 + Layout.preferredWidth: 7 * 52 + 20 - 6 + palette: Nheko.colors + background: null + placeholderTextColor: Nheko.colors.buttonText + color: Nheko.colors.text + placeholderText: qsTr("Search") + selectByMouse: true + rightPadding: clearSearch.width + onTextChanged: searchTimer.restart() + onVisibleChanged: { + if (visible) + forceActiveFocus(); } - delegate: AbstractButton { - Layout.preferredWidth: 36 - Layout.preferredHeight: 36 + Timer { + id: searchTimer + + interval: 350 // tweak as needed? + onTriggered: { + emojiPopup.model.searchString = emojiSearch.text; + emojiPopup.model.category = Emoji.Category.Search; + } + } + + ToolButton { + id: clearSearch + + visible: emojiSearch.text !== '' + icon.source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + focusPolicy: Qt.NoFocus + onClicked: emojiSearch.clear() hoverEnabled: true - ToolTip.text: { - switch (model.category) { - case Emoji.Category.People: - return qsTr('People'); - case Emoji.Category.Nature: - return qsTr('Nature'); - case Emoji.Category.Food: - return qsTr('Food'); - case Emoji.Category.Activity: - return qsTr('Activity'); - case Emoji.Category.Travel: - return qsTr('Travel'); - case Emoji.Category.Objects: - return qsTr('Objects'); - case Emoji.Category.Symbols: - return qsTr('Symbols'); - case Emoji.Category.Flags: - return qsTr('Flags'); + background: null + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + } + // clear the default hover effects. + + Image { + height: parent.height - 2 * Nheko.paddingSmall + width: height + source: "image://colorimage/:/icons/icons/ui/round-remove-button.png?" + (clearSearch.hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + margins: Nheko.paddingSmall } + } + + } + + } + + // emoji grid + GridView { + id: gridView + + Layout.preferredHeight: cellHeight * 5 + Layout.preferredWidth: 7 * 52 + 20 + Layout.leftMargin: 4 + cellWidth: 52 + cellHeight: 52 + boundsBehavior: Flickable.StopAtBounds + clip: true + currentIndex: -1 // prevent sorting from stealing focus + + // Individual emoji + delegate: AbstractButton { + width: 48 + height: 48 + hoverEnabled: true + ToolTip.text: model.shortName ToolTip.visible: hovered + // TODO: maybe add favorites at some point? onClicked: { - //emojiPopup.model.category = model.category; - gridView.positionViewAtIndex(emojiPopup.model.sourceModel.categoryToIndex(model.category), GridView.Beginning); + console.debug("Picked " + model.unicode); + emojiPopup.close(); + callback(model.unicode); } - MouseArea { - id: mouseArea - - anchors.fill: parent - onPressed: mouse.accepted = false - cursorShape: Qt.PointingHandCursor + // give the emoji a little oomf + DropShadow { + width: parent.width + height: parent.height + horizontalOffset: 3 + verticalOffset: 3 + radius: 8 + samples: 17 + color: "#80000000" + source: parent.contentItem } - contentItem: Image { - horizontalAlignment: Image.AlignHCenter - verticalAlignment: Image.AlignVCenter - fillMode: Image.Pad - sourceSize.width: 32 - sourceSize.height: 32 - source: "image://colorimage/" + model.image + "?" + (hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + contentItem: Text { + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + font.family: Settings.emojiFont + font.pixelSize: 36 + text: model.unicode + color: Nheko.colors.text } background: Rectangle { anchors.fill: parent - color: emojiPopup.model.category === model.category ? Qt.hsla(highlightHue, highlightSat, highlightLight, 0.2) : 'transparent' + color: hovered ? Nheko.colors.highlight : 'transparent' radius: 5 - border.color: emojiPopup.model.category === model.category ? Nheko.colors.highlight : 'transparent' + } + + } + + ScrollBar.vertical: ScrollBar { + id: emojiScroll + } + + } + + // Separator + Rectangle { + visible: emojiSearch.text === '' + Layout.fillWidth: true + Layout.preferredHeight: 1 + color: emojiPopup.Nheko.theme.separator + } + + // Category picker row + RowLayout { + visible: emojiSearch.text === '' + Layout.bottomMargin: 0 + Layout.preferredHeight: 42 + implicitHeight: 42 + Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom + + // Display the normal categories + Repeater { + + model: ListModel { + // TODO: Would like to get 'simple' icons for the categories + ListElement { + image: ":/icons/icons/emoji-categories/people.png" + category: Emoji.Category.People + } + + ListElement { + image: ":/icons/icons/emoji-categories/nature.png" + category: Emoji.Category.Nature + } + + ListElement { + image: ":/icons/icons/emoji-categories/foods.png" + category: Emoji.Category.Food + } + + ListElement { + image: ":/icons/icons/emoji-categories/activity.png" + category: Emoji.Category.Activity + } + + ListElement { + image: ":/icons/icons/emoji-categories/travel.png" + category: Emoji.Category.Travel + } + + ListElement { + image: ":/icons/icons/emoji-categories/objects.png" + category: Emoji.Category.Objects + } + + ListElement { + image: ":/icons/icons/emoji-categories/symbols.png" + category: Emoji.Category.Symbols + } + + ListElement { + image: ":/icons/icons/emoji-categories/flags.png" + category: Emoji.Category.Flags + } + + } + + delegate: AbstractButton { + Layout.preferredWidth: 36 + Layout.preferredHeight: 36 + hoverEnabled: true + ToolTip.text: { + switch (model.category) { + case Emoji.Category.People: + return qsTr('People'); + case Emoji.Category.Nature: + return qsTr('Nature'); + case Emoji.Category.Food: + return qsTr('Food'); + case Emoji.Category.Activity: + return qsTr('Activity'); + case Emoji.Category.Travel: + return qsTr('Travel'); + case Emoji.Category.Objects: + return qsTr('Objects'); + case Emoji.Category.Symbols: + return qsTr('Symbols'); + case Emoji.Category.Flags: + return qsTr('Flags'); + } + } + ToolTip.visible: hovered + onClicked: { + //emojiPopup.model.category = model.category; + gridView.positionViewAtIndex(emojiPopup.model.sourceModel.categoryToIndex(model.category), GridView.Beginning); + } + + MouseArea { + id: mouseArea + + anchors.fill: parent + onPressed: mouse.accepted = false + cursorShape: Qt.PointingHandCursor + } + + contentItem: Image { + horizontalAlignment: Image.AlignHCenter + verticalAlignment: Image.AlignVCenter + fillMode: Image.Pad + sourceSize.width: 32 + sourceSize.height: 32 + source: "image://colorimage/" + model.image + "?" + (hovered ? Nheko.colors.highlight : Nheko.colors.buttonText) + } + + background: Rectangle { + anchors.fill: parent + color: emojiPopup.model.category === model.category ? Qt.hsla(highlightHue, highlightSat, highlightLight, 0.2) : 'transparent' + radius: 5 + border.color: emojiPopup.model.category === model.category ? Nheko.colors.highlight : 'transparent' + } + } } diff --git a/resources/res.qrc b/resources/res.qrc index 8f24d33b..913de9d5 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -125,6 +125,7 @@ qml/Root.qml qml/ChatPage.qml + qml/CommunitiesList.qml qml/RoomList.qml qml/TimelineView.qml qml/Avatar.qml diff --git a/src/Cache.cpp b/src/Cache.cpp index 4a99dd59..8146e2cc 100644 --- a/src/Cache.cpp +++ b/src/Cache.cpp @@ -55,6 +55,10 @@ constexpr auto BATCH_SIZE = 100; //! Format: room_id -> RoomInfo constexpr auto ROOMS_DB("rooms"); constexpr auto INVITES_DB("invites"); +//! maps each room to its parent space (id->id) +constexpr auto SPACES_PARENTS_DB("space_parents"); +//! maps each space to its current children (id->id) +constexpr auto SPACES_CHILDREN_DB("space_children"); //! Information that must be kept between sync requests. constexpr auto SYNC_STATE_DB("sync_state"); //! Read receipts per room/event. @@ -237,12 +241,14 @@ Cache::setup() env_.open(cacheDirectory_.toStdString().c_str()); } - auto txn = lmdb::txn::begin(env_); - syncStateDb_ = lmdb::dbi::open(txn, SYNC_STATE_DB, MDB_CREATE); - roomsDb_ = lmdb::dbi::open(txn, ROOMS_DB, MDB_CREATE); - invitesDb_ = lmdb::dbi::open(txn, INVITES_DB, MDB_CREATE); - readReceiptsDb_ = lmdb::dbi::open(txn, READ_RECEIPTS_DB, MDB_CREATE); - notificationsDb_ = lmdb::dbi::open(txn, NOTIFICATIONS_DB, MDB_CREATE); + auto txn = lmdb::txn::begin(env_); + syncStateDb_ = lmdb::dbi::open(txn, SYNC_STATE_DB, MDB_CREATE); + roomsDb_ = lmdb::dbi::open(txn, ROOMS_DB, MDB_CREATE); + spacesChildrenDb_ = lmdb::dbi::open(txn, SPACES_CHILDREN_DB, MDB_CREATE | MDB_DUPSORT); + spacesParentsDb_ = lmdb::dbi::open(txn, SPACES_PARENTS_DB, MDB_CREATE | MDB_DUPSORT); + invitesDb_ = lmdb::dbi::open(txn, INVITES_DB, MDB_CREATE); + readReceiptsDb_ = lmdb::dbi::open(txn, READ_RECEIPTS_DB, MDB_CREATE); + notificationsDb_ = lmdb::dbi::open(txn, NOTIFICATIONS_DB, MDB_CREATE); // Device management devicesDb_ = lmdb::dbi::open(txn, DEVICES_DB, MDB_CREATE); @@ -899,7 +905,9 @@ Cache::runMigrations() std::reverse(oldMessages.events.begin(), oldMessages.events.end()); // save messages using the new method - saveTimelineMessages(txn, room_id, oldMessages); + auto eventsDb = getEventsDb(txn, room_id); + saveTimelineMessages( + txn, eventsDb, room_id, oldMessages); } // delete old messages db @@ -1194,24 +1202,73 @@ Cache::saveState(const mtx::responses::Sync &res) auto userKeyCacheDb = getUserKeysDb(txn); + std::set spaces_with_updates; + std::set rooms_with_space_updates; + // Save joined rooms for (const auto &room : res.rooms.join) { auto statesdb = getStatesDb(txn, room.first); auto stateskeydb = getStatesKeyDb(txn, room.first); auto membersdb = getMembersDb(txn, room.first); + auto eventsDb = getEventsDb(txn, room.first); - saveStateEvents( - txn, statesdb, stateskeydb, membersdb, room.first, room.second.state.events); - saveStateEvents( - txn, statesdb, stateskeydb, membersdb, room.first, room.second.timeline.events); + saveStateEvents(txn, + statesdb, + stateskeydb, + membersdb, + eventsDb, + room.first, + room.second.state.events); + saveStateEvents(txn, + statesdb, + stateskeydb, + membersdb, + eventsDb, + room.first, + room.second.timeline.events); - saveTimelineMessages(txn, room.first, room.second.timeline); + saveTimelineMessages(txn, eventsDb, room.first, room.second.timeline); RoomInfo updatedInfo; updatedInfo.name = getRoomName(txn, statesdb, membersdb).toStdString(); updatedInfo.topic = getRoomTopic(txn, statesdb).toStdString(); updatedInfo.avatar_url = getRoomAvatarUrl(txn, statesdb, membersdb).toStdString(); updatedInfo.version = getRoomVersion(txn, statesdb).toStdString(); + updatedInfo.is_space = getRoomIsSpace(txn, statesdb); + + if (updatedInfo.is_space) { + bool space_updates = false; + for (const auto &e : room.second.state.events) + if (std::holds_alternative>(e) || + std::holds_alternative>(e)) + space_updates = true; + for (const auto &e : room.second.timeline.events) + if (std::holds_alternative>(e) || + std::holds_alternative>(e)) + space_updates = true; + + if (space_updates) + spaces_with_updates.insert(room.first); + } + + { + bool room_has_space_update = false; + for (const auto &e : room.second.state.events) { + if (auto se = std::get_if>(&e)) { + spaces_with_updates.insert(se->state_key); + room_has_space_update = true; + } + } + for (const auto &e : room.second.timeline.events) { + if (auto se = std::get_if>(&e)) { + spaces_with_updates.insert(se->state_key); + room_has_space_update = true; + } + } + + if (room_has_space_update) + rooms_with_space_updates.insert(room.first); + } bool has_new_tags = false; // Process the account_data associated with this room @@ -1291,6 +1348,8 @@ Cache::saveState(const mtx::responses::Sync &res) removeLeftRooms(txn, res.rooms.leave); + updateSpaces(txn, spaces_with_updates, std::move(rooms_with_space_updates)); + txn.commit(); std::map readStatus; @@ -1339,6 +1398,7 @@ Cache::saveInvites(lmdb::txn &txn, const std::map -Cache::roomsWithTagUpdates(const mtx::responses::Sync &res) -{ - using namespace mtx::events; - - std::vector rooms; - for (const auto &room : res.rooms.join) { - bool hasUpdates = false; - for (const auto &evt : room.second.account_data.events) { - if (std::holds_alternative>(evt)) { - hasUpdates = true; - } - } - - if (hasUpdates) - rooms.emplace_back(room.first); - } - - return rooms; -} - RoomInfo Cache::singleRoomInfo(const std::string &room_id) { @@ -1681,6 +1720,27 @@ Cache::storeEvent(const std::string &room_id, txn.commit(); } +void +Cache::replaceEvent(const std::string &room_id, + const std::string &event_id, + const mtx::events::collections::TimelineEvent &event) +{ + auto txn = lmdb::txn::begin(env_); + auto eventsDb = getEventsDb(txn, room_id); + auto relationsDb = getRelationsDb(txn, room_id); + auto event_json = mtx::accessors::serialize_event(event.data).dump(); + + { + eventsDb.del(txn, event_id); + eventsDb.put(txn, event_id, event_json); + for (auto relation : mtx::accessors::relations(event.data).relations) { + relationsDb.put(txn, relation.event_id, event_id); + } + } + + txn.commit(); +} + std::vector Cache::relatedEvents(const std::string &room_id, const std::string &event_id) { @@ -1712,6 +1772,13 @@ Cache::relatedEvents(const std::string &room_id, const std::string &event_id) return related_ids; } +size_t +Cache::memberCount(const std::string &room_id) +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + return getMembersDb(txn, room_id).size(txn); +} + QMap Cache::roomInfo(bool withInvites) { @@ -1727,8 +1794,6 @@ Cache::roomInfo(bool withInvites) while (roomsCursor.get(room_id, room_data, MDB_NEXT)) { RoomInfo tmp = json::parse(std::move(room_data)); tmp.member_count = getMembersDb(txn, std::string(room_id)).size(txn); - tmp.msgInfo = getLastMessageInfo(txn, std::string(room_id)); - result.insert(QString::fromStdString(std::string(room_id)), std::move(tmp)); } roomsCursor.close(); @@ -1955,96 +2020,6 @@ Cache::getTimelineEventId(const std::string &room_id, uint64_t index) return std::string(val); } -DescInfo -Cache::getLastMessageInfo(lmdb::txn &txn, const std::string &room_id) -{ - lmdb::dbi orderDb; - try { - orderDb = getOrderToMessageDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - lmdb::dbi eventsDb; - try { - eventsDb = getEventsDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - lmdb::dbi membersdb; - try { - membersdb = getMembersDb(txn, room_id); - } catch (lmdb::runtime_error &e) { - nhlog::db()->error("Can't open db for room '{}', probably doesn't exist yet. ({})", - room_id, - e.what()); - return {}; - } - - if (orderDb.size(txn) == 0) - return DescInfo{}; - - const auto local_user = utils::localUser(); - - DescInfo fallbackDesc{}; - - std::string_view indexVal, event_id; - - auto cursor = lmdb::cursor::open(txn, orderDb); - bool first = true; - while (cursor.get(indexVal, event_id, first ? MDB_LAST : MDB_PREV)) { - first = false; - - std::string_view event; - bool success = eventsDb.get(txn, event_id, event); - if (!success) - continue; - - auto obj = json::parse(event); - - if (fallbackDesc.event_id.isEmpty() && obj["type"] == "m.room.member" && - obj["state_key"] == local_user.toStdString() && - obj["content"]["membership"] == "join") { - uint64_t ts = obj["origin_server_ts"]; - auto time = QDateTime::fromMSecsSinceEpoch(ts); - fallbackDesc = DescInfo{QString::fromStdString(obj["event_id"]), - local_user, - tr("You joined this room."), - utils::descriptiveTime(time), - ts, - time}; - } - - if (!(obj["type"] == "m.room.message" || obj["type"] == "m.sticker" || - obj["type"] == "m.call.invite" || obj["type"] == "m.call.answer" || - obj["type"] == "m.call.hangup" || obj["type"] == "m.room.encrypted")) - continue; - - mtx::events::collections::TimelineEvent te; - mtx::events::collections::from_json(obj, te); - - std::string_view info; - MemberInfo m; - if (membersdb.get(txn, obj["sender"].get(), info)) { - m = json::parse(std::string_view(info.data(), info.size())); - } - - cursor.close(); - return utils::getMessageDescription( - te.data, local_user, QString::fromStdString(m.name)); - } - cursor.close(); - - return fallbackDesc; -} - QHash Cache::invites() { @@ -2316,6 +2291,29 @@ Cache::getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb) return QString("1"); } +bool +Cache::getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb) +{ + using namespace mtx::events; + using namespace mtx::events::state; + + std::string_view event; + bool res = statesdb.get(txn, to_string(mtx::events::EventType::RoomCreate), event); + + if (res) { + try { + StateEvent msg = json::parse(event); + + return msg.content.type == mtx::events::state::room_type::space; + } catch (const json::exception &e) { + nhlog::db()->warn("failed to parse m.room.create event: {}", e.what()); + } + } + + nhlog::db()->warn("m.room.create event is missing room version, assuming version \"1\""); + return false; +} + std::optional Cache::getRoomAliases(const std::string &roomid) { @@ -2443,6 +2441,27 @@ Cache::getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &db) return QString(); } +bool +Cache::getInviteRoomIsSpace(lmdb::txn &txn, lmdb::dbi &db) +{ + using namespace mtx::events; + using namespace mtx::events::state; + + std::string_view event; + bool res = db.get(txn, to_string(mtx::events::EventType::RoomCreate), event); + + if (res) { + try { + StrippedEvent msg = json::parse(event); + return msg.content.type == mtx::events::state::room_type::space; + } catch (const json::exception &e) { + nhlog::db()->warn("failed to parse m.room.topic event: {}", e.what()); + } + } + + return false; +} + std::vector Cache::joinedRooms() { @@ -2479,47 +2498,12 @@ Cache::getMember(const std::string &room_id, const std::string &user_id) return m; } } catch (std::exception &e) { - nhlog::db()->warn("Failed to read member ({}): {}", user_id, e.what()); + nhlog::db()->warn( + "Failed to read member ({}) in room ({}): {}", user_id, room_id, e.what()); } return std::nullopt; } -std::vector -Cache::searchRooms(const std::string &query, std::uint8_t max_items) -{ - std::multimap> items; - - auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); - auto cursor = lmdb::cursor::open(txn, roomsDb_); - - std::string_view room_id, room_data; - while (cursor.get(room_id, room_data, MDB_NEXT)) { - RoomInfo tmp = json::parse(room_data); - - const int score = utils::levenshtein_distance( - query, QString::fromStdString(tmp.name).toLower().toStdString()); - items.emplace(score, std::make_pair(room_id, tmp)); - } - - cursor.close(); - - auto end = items.begin(); - - if (items.size() >= max_items) - std::advance(end, max_items); - else if (items.size() > 0) - std::advance(end, items.size()); - - std::vector results; - for (auto it = items.begin(); it != end; it++) { - results.push_back(RoomSearchResult{it->second.first, it->second.second}); - } - - txn.commit(); - - return results; -} - std::vector Cache::getMembers(const std::string &room_id, std::size_t startIndex, std::size_t len) { @@ -2578,11 +2562,12 @@ void Cache::savePendingMessage(const std::string &room_id, const mtx::events::collections::TimelineEvent &message) { - auto txn = lmdb::txn::begin(env_); + auto txn = lmdb::txn::begin(env_); + auto eventsDb = getEventsDb(txn, room_id); mtx::responses::Timeline timeline; timeline.events.push_back(message.data); - saveTimelineMessages(txn, room_id, timeline); + saveTimelineMessages(txn, eventsDb, room_id, timeline); auto pending = getPendingMessagesDb(txn, room_id); @@ -2650,13 +2635,13 @@ Cache::removePendingStatus(const std::string &room_id, const std::string &txn_id void Cache::saveTimelineMessages(lmdb::txn &txn, + lmdb::dbi &eventsDb, const std::string &room_id, const mtx::responses::Timeline &res) { if (res.events.empty()) return; - auto eventsDb = getEventsDb(txn, room_id); auto relationsDb = getRelationsDb(txn, room_id); auto orderDb = getEventOrderDb(txn, room_id); @@ -3181,6 +3166,147 @@ Cache::deleteOldData() noexcept } } +void +Cache::updateSpaces(lmdb::txn &txn, + const std::set &spaces_with_updates, + std::set rooms_with_updates) +{ + if (spaces_with_updates.empty() && rooms_with_updates.empty()) + return; + + for (const auto &space : spaces_with_updates) { + // delete old entries + { + auto cursor = lmdb::cursor::open(txn, spacesChildrenDb_); + bool first = true; + std::string_view sp = space, space_child = ""; + + if (cursor.get(sp, space_child, MDB_SET)) { + while (cursor.get( + sp, space_child, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) { + first = false; + spacesParentsDb_.del(txn, space_child, space); + } + } + cursor.close(); + spacesChildrenDb_.del(txn, space); + } + + for (const auto &event : + getStateEventsWithType(txn, space)) { + if (event.content.via.has_value() && event.state_key.size() > 3 && + event.state_key.at(0) == '!') { + spacesChildrenDb_.put(txn, space, event.state_key); + spacesParentsDb_.put(txn, event.state_key, space); + } + } + } + + const auto space_event_type = to_string(mtx::events::EventType::RoomPowerLevels); + + for (const auto &room : rooms_with_updates) { + for (const auto &event : + getStateEventsWithType(txn, room)) { + if (event.content.via.has_value() && event.state_key.size() > 3 && + event.state_key.at(0) == '!') { + const std::string &space = event.state_key; + + auto pls = + getStateEvent(txn, space); + + if (!pls) + continue; + + if (pls->content.user_level(event.sender) >= + pls->content.state_level(space_event_type)) { + spacesChildrenDb_.put(txn, space, room); + spacesParentsDb_.put(txn, room, space); + } + } + } + } +} + +QMap> +Cache::spaces() +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + QMap> ret; + { + auto cursor = lmdb::cursor::open(txn, spacesChildrenDb_); + bool first = true; + std::string_view space_id, space_child; + while (cursor.get(space_id, space_child, first ? MDB_FIRST : MDB_NEXT)) { + first = false; + + if (!space_child.empty()) { + std::string_view room_data; + if (roomsDb_.get(txn, space_id, room_data)) { + RoomInfo tmp = json::parse(std::move(room_data)); + ret.insert( + QString::fromUtf8(space_id.data(), space_id.size()), tmp); + } else { + ret.insert( + QString::fromUtf8(space_id.data(), space_id.size()), + std::nullopt); + } + } + } + cursor.close(); + } + + return ret; +} + +std::vector +Cache::getParentRoomIds(const std::string &room_id) +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + std::vector roomids; + { + auto cursor = lmdb::cursor::open(txn, spacesParentsDb_); + bool first = true; + std::string_view sp = room_id, space_parent; + if (cursor.get(sp, space_parent, MDB_SET)) { + while (cursor.get(sp, space_parent, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) { + first = false; + + if (!space_parent.empty()) + roomids.emplace_back(space_parent); + } + } + cursor.close(); + } + + return roomids; +} + +std::vector +Cache::getChildRoomIds(const std::string &room_id) +{ + auto txn = lmdb::txn::begin(env_, nullptr, MDB_RDONLY); + + std::vector roomids; + { + auto cursor = lmdb::cursor::open(txn, spacesChildrenDb_); + bool first = true; + std::string_view sp = room_id, space_child; + if (cursor.get(sp, space_child, MDB_SET)) { + while (cursor.get(sp, space_child, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) { + first = false; + + if (!space_child.empty()) + roomids.emplace_back(space_child); + } + } + cursor.close(); + } + + return roomids; +} + std::optional Cache::getAccountData(lmdb::txn &txn, mtx::events::EventType type, const std::string &room_id) { @@ -3451,6 +3577,10 @@ Cache::updateUserKeys(const std::string &sync_token, const mtx::responses::Query if (!updateToWrite.master_keys.keys.empty() && update.master_keys.keys != updateToWrite.master_keys.keys) { + nhlog::db()->debug("Master key of {} changed:\nold: {}\nnew: {}", + user, + updateToWrite.master_keys.keys.size(), + update.master_keys.keys.size()); updateToWrite.master_key_changed = true; } @@ -3458,25 +3588,31 @@ Cache::updateUserKeys(const std::string &sync_token, const mtx::responses::Query updateToWrite.self_signing_keys = update.self_signing_keys; updateToWrite.user_signing_keys = update.user_signing_keys; - // If we have keys for the device already, only update the signatures. + auto oldDeviceKeys = std::move(updateToWrite.device_keys); + updateToWrite.device_keys.clear(); + + // Don't insert keys, which we have seen once already for (const auto &[device_id, device_keys] : update.device_keys) { - if (updateToWrite.device_keys.count(device_id) && - updateToWrite.device_keys.at(device_id).keys == - device_keys.keys) { - updateToWrite.device_keys.at(device_id).signatures = - device_keys.signatures; + if (oldDeviceKeys.count(device_id) && + oldDeviceKeys.at(device_id).keys == device_keys.keys) { + // this is safe, since the keys are the same + updateToWrite.device_keys[device_id] = device_keys; } else { bool keyReused = false; for (const auto &[key_id, key] : device_keys.keys) { (void)key_id; if (updateToWrite.seen_device_keys.count(key)) { + nhlog::crypto()->warn( + "Key '{}' reused by ({}: {})", + key, + user, + device_id); keyReused = true; break; } } - if (!updateToWrite.device_keys.count(device_id) && - !keyReused) + if (!keyReused && !oldDeviceKeys.count(device_id)) updateToWrite.device_keys[device_id] = device_keys; } @@ -3858,6 +3994,7 @@ to_json(json &j, const RoomInfo &info) j["avatar_url"] = info.avatar_url; j["version"] = info.version; j["is_invite"] = info.is_invite; + j["is_space"] = info.is_space; j["join_rule"] = info.join_rule; j["guest_access"] = info.guest_access; @@ -3877,6 +4014,7 @@ from_json(const json &j, RoomInfo &info) info.version = j.value( "version", QCoreApplication::translate("RoomInfo", "no version stored").toStdString()); info.is_invite = j.at("is_invite"); + info.is_space = j.value("is_space", false); info.join_rule = j.at("join_rule"); info.guest_access = j.at("guest_access"); @@ -4132,12 +4270,6 @@ getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb) return instance_->getRoomAvatarUrl(txn, statesdb, membersdb); } -QString -getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb) -{ - return instance_->getRoomVersion(txn, statesdb); -} - std::vector getMembers(const std::string &room_id, std::size_t startIndex, std::size_t len) { @@ -4279,11 +4411,7 @@ roomsWithStateUpdates(const mtx::responses::Sync &res) { return instance_->roomsWithStateUpdates(res); } -std::vector -roomsWithTagUpdates(const mtx::responses::Sync &res) -{ - return instance_->roomsWithTagUpdates(res); -} + std::map getRoomInfo(const std::vector &rooms) { @@ -4303,12 +4431,6 @@ calculateRoomReadStatus() instance_->calculateRoomReadStatus(); } -std::vector -searchRooms(const std::string &query, std::uint8_t max_items) -{ - return instance_->searchRooms(query, max_items); -} - void markSentNotification(const std::string &event_id) { diff --git a/src/Cache.h b/src/Cache.h index 74ec9695..b0520f6b 100644 --- a/src/Cache.h +++ b/src/Cache.h @@ -79,9 +79,6 @@ getRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); //! Retrieve the room avatar's url if any. QString getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); -//! Retrieve the version of the room if any. -QString -getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb); //! Retrieve member info from a room. std::vector @@ -166,9 +163,6 @@ calculateRoomReadStatus(const std::string &room_id); void calculateRoomReadStatus(); -std::vector -searchRooms(const std::string &query, std::uint8_t max_items = 5); - void markSentNotification(const std::string &event_id); //! Removes an event from the sent notifications. diff --git a/src/CacheStructs.h b/src/CacheStructs.h index f7d6f0e2..28c70055 100644 --- a/src/CacheStructs.h +++ b/src/CacheStructs.h @@ -76,13 +76,13 @@ struct RoomInfo std::string version; //! Whether or not the room is an invite. bool is_invite = false; + //! Wheter or not the room is a space + bool is_space = false; //! Total number of members in the room. size_t member_count = 0; //! Who can access to the room. mtx::events::state::JoinRule join_rule = mtx::events::state::JoinRule::Public; bool guest_access = false; - //! Metadata describing the last message in the timeline. - DescInfo msgInfo; //! The list of tags associated with this room std::vector tags; }; diff --git a/src/Cache_p.h b/src/Cache_p.h index f2911622..c76cc717 100644 --- a/src/Cache_p.h +++ b/src/Cache_p.h @@ -72,6 +72,7 @@ public: std::optional getRoomAliases(const std::string &roomid); QHash invites(); std::optional invite(std::string_view roomid); + QMap> spaces(); //! Calculate & return the name of the room. QString getRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); @@ -84,6 +85,8 @@ public: QString getRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); //! Retrieve the version of the room if any. QString getRoomVersion(lmdb::txn &txn, lmdb::dbi &statesdb); + //! Retrieve if the room is a space + bool getRoomIsSpace(lmdb::txn &txn, lmdb::dbi &statesdb); //! Get a specific state event template @@ -98,6 +101,7 @@ public: std::vector getMembers(const std::string &room_id, std::size_t startIndex = 0, std::size_t len = 30); + size_t memberCount(const std::string &room_id); void saveState(const mtx::responses::Sync &res); bool isInitialized(); @@ -146,7 +150,6 @@ public: RoomInfo singleRoomInfo(const std::string &room_id); std::vector roomsWithStateUpdates(const mtx::responses::Sync &res); - std::vector roomsWithTagUpdates(const mtx::responses::Sync &res); std::map getRoomInfo(const std::vector &rooms); //! Calculates which the read status of a room. @@ -154,9 +157,6 @@ public: bool calculateRoomReadStatus(const std::string &room_id); void calculateRoomReadStatus(); - std::vector searchRooms(const std::string &query, - std::uint8_t max_items = 5); - void markSentNotification(const std::string &event_id); //! Removes an event from the sent notifications. void removeReadNotification(const std::string &event_id); @@ -184,6 +184,9 @@ public: void storeEvent(const std::string &room_id, const std::string &event_id, const mtx::events::collections::TimelineEvent &event); + void replaceEvent(const std::string &room_id, + const std::string &event_id, + const mtx::events::collections::TimelineEvent &event); std::vector relatedEvents(const std::string &room_id, const std::string &event_id); @@ -219,6 +222,8 @@ public: void deleteOldData() noexcept; //! Retrieve all saved room ids. std::vector getRoomIds(lmdb::txn &txn); + std::vector getParentRoomIds(const std::string &room_id); + std::vector getChildRoomIds(const std::string &room_id); //! Mark a room that uses e2e encryption. void setEncryptedRoom(lmdb::txn &txn, const std::string &room_id); @@ -324,12 +329,13 @@ private: QString getInviteRoomName(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); QString getInviteRoomTopic(lmdb::txn &txn, lmdb::dbi &statesdb); QString getInviteRoomAvatarUrl(lmdb::txn &txn, lmdb::dbi &statesdb, lmdb::dbi &membersdb); + bool getInviteRoomIsSpace(lmdb::txn &txn, lmdb::dbi &db); std::optional getMember(const std::string &room_id, const std::string &user_id); std::string getLastEventId(lmdb::txn &txn, const std::string &room_id); - DescInfo getLastMessageInfo(lmdb::txn &txn, const std::string &room_id); void saveTimelineMessages(lmdb::txn &txn, + lmdb::dbi &eventsDb, const std::string &room_id, const mtx::responses::Timeline &res); @@ -348,11 +354,12 @@ private: lmdb::dbi &statesdb, lmdb::dbi &stateskeydb, lmdb::dbi &membersdb, + lmdb::dbi &eventsDb, const std::string &room_id, const std::vector &events) { for (const auto &e : events) - saveStateEvent(txn, statesdb, stateskeydb, membersdb, room_id, e); + saveStateEvent(txn, statesdb, stateskeydb, membersdb, eventsDb, room_id, e); } template @@ -360,6 +367,7 @@ private: lmdb::dbi &statesdb, lmdb::dbi &stateskeydb, lmdb::dbi &membersdb, + lmdb::dbi &eventsDb, const std::string &room_id, const T &event) { @@ -396,8 +404,10 @@ private: } std::visit( - [&txn, &statesdb, &stateskeydb](auto e) { - if constexpr (isStateEvent(e)) + [&txn, &statesdb, &stateskeydb, &eventsDb](auto e) { + if constexpr (isStateEvent(e)) { + eventsDb.put(txn, e.event_id, json(e).dump()); + if (e.type != EventType::Unsupported) { if (e.state_key.empty()) statesdb.put( @@ -412,6 +422,7 @@ private: }) .dump()); } + } }, event); } @@ -427,20 +438,22 @@ private: if (room_id.empty()) return std::nullopt; + const auto typeStr = to_string(type); std::string_view value; if (state_key.empty()) { auto db = getStatesDb(txn, room_id); - if (!db.get(txn, to_string(type), value)) { + if (!db.get(txn, typeStr, value)) { return std::nullopt; } } else { - auto db = getStatesKeyDb(txn, room_id); - std::string d = json::object({{"key", state_key}}).dump(); - std::string_view data = d; + auto db = getStatesKeyDb(txn, room_id); + std::string d = json::object({{"key", state_key}}).dump(); + std::string_view data = d; + std::string_view typeStrV = typeStr; auto cursor = lmdb::cursor::open(txn, db); - if (!cursor.get(state_key, data, MDB_GET_BOTH)) + if (!cursor.get(typeStrV, data, MDB_GET_BOTH)) return std::nullopt; try { @@ -460,6 +473,47 @@ private: } } + template + std::vector> getStateEventsWithType(lmdb::txn &txn, + const std::string &room_id) + + { + constexpr auto type = mtx::events::state_content_to_type; + static_assert(type != mtx::events::EventType::Unsupported, + "Not a supported type in state events."); + + if (room_id.empty()) + return {}; + + std::vector> events; + + { + auto db = getStatesKeyDb(txn, room_id); + auto eventsDb = getEventsDb(txn, room_id); + const auto typeStr = to_string(type); + std::string_view typeStrV = typeStr; + std::string_view data; + std::string_view value; + + auto cursor = lmdb::cursor::open(txn, db); + bool first = true; + if (cursor.get(typeStrV, data, MDB_SET)) { + while (cursor.get( + typeStrV, data, first ? MDB_FIRST_DUP : MDB_NEXT_DUP)) { + first = false; + + if (eventsDb.get(txn, + json::parse(data)["id"].get(), + value)) + events.push_back( + json::parse(value) + .get>()); + } + } + } + + return events; + } void saveInvites(lmdb::txn &txn, const std::map &rooms); @@ -479,6 +533,10 @@ private: } } + void updateSpaces(lmdb::txn &txn, + const std::set &spaces_with_updates, + std::set rooms_with_updates); + lmdb::dbi getPendingReceiptsDb(lmdb::txn &txn) { return lmdb::dbi::open(txn, "pending_receipts", MDB_CREATE); @@ -545,8 +603,8 @@ private: lmdb::dbi getStatesKeyDb(lmdb::txn &txn, const std::string &room_id) { - auto db = - lmdb::dbi::open(txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE); + auto db = lmdb::dbi::open( + txn, std::string(room_id + "/state_by_key").c_str(), MDB_CREATE | MDB_DUPSORT); lmdb::dbi_set_dupsort(txn, db, compare_state_key); return db; } @@ -608,6 +666,7 @@ private: lmdb::env env_; lmdb::dbi syncStateDb_; lmdb::dbi roomsDb_; + lmdb::dbi spacesChildrenDb_, spacesParentsDb_; lmdb::dbi invitesDb_; lmdb::dbi readReceiptsDb_; lmdb::dbi notificationsDb_; diff --git a/src/ChatPage.cpp b/src/ChatPage.cpp index 0f16f205..6003eb85 100644 --- a/src/ChatPage.cpp +++ b/src/ChatPage.cpp @@ -550,7 +550,7 @@ ChatPage::startInitialSync() nhlog::net()->error("initial sync error: {} {} {} {}", err->parse_error, status_code, - err->error_code.message(), + err->error_code, err_code); // non http related errors @@ -674,10 +674,10 @@ ChatPage::trySync() return; } - nhlog::net()->error("initial sync error: {} {} {} {}", + nhlog::net()->error("sync error: {} {} {} {}", err->parse_error, status_code, - err->error_code.message(), + err->error_code, err_code); emit tryDelayedSyncCb(); return; diff --git a/src/LoginPage.cpp b/src/LoginPage.cpp index c914d66f..f53d81ba 100644 --- a/src/LoginPage.cpp +++ b/src/LoginPage.cpp @@ -263,9 +263,7 @@ LoginPage::onMatrixIdEntered() http::client()->well_known([this](const mtx::responses::WellKnown &res, mtx::http::RequestErr err) { if (err) { - using namespace boost::beast::http; - - if (err->status_code == status::not_found) { + if (err->status_code == 404) { nhlog::net()->info("Autodiscovery: No .well-known."); checkHomeserverVersion(); return; @@ -282,8 +280,9 @@ LoginPage::onMatrixIdEntered() emit versionErrorCb(tr("Autodiscovery failed. Unknown error when " "requesting .well-known.")); nhlog::net()->error("Autodiscovery failed. Unknown error when " - "requesting .well-known. {}", - err->error_code.message()); + "requesting .well-known. {} {}", + err->status_code, + err->error_code); return; } @@ -301,9 +300,7 @@ LoginPage::checkHomeserverVersion() http::client()->versions( [this](const mtx::responses::Versions &, mtx::http::RequestErr err) { if (err) { - using namespace boost::beast::http; - - if (err->status_code == status::not_found) { + if (err->status_code == 404) { emit versionErrorCb(tr("The required endpoints were not found. " "Possibly not a Matrix server.")); return; diff --git a/src/Olm.cpp b/src/Olm.cpp index d08c1b3e..ff4c883b 100644 --- a/src/Olm.cpp +++ b/src/Olm.cpp @@ -206,8 +206,11 @@ handle_olm_message(const OlmMessage &msg) for (const auto &cipher : msg.ciphertext) { // We skip messages not meant for the current device. - if (cipher.first != my_key) + if (cipher.first != my_key) { + nhlog::crypto()->debug( + "Skipping message for {} since we are {}.", cipher.first, my_key); continue; + } const auto type = cipher.second.type; nhlog::crypto()->info("type: {}", type == 0 ? "OLM_PRE_KEY" : "OLM_MESSAGE"); @@ -661,8 +664,10 @@ try_olm_decryption(const std::string &sender_key, const mtx::events::msg::OlmCip for (const auto &id : session_ids) { auto session = cache::getOlmSession(sender_key, id); - if (!session) + if (!session) { + nhlog::crypto()->warn("Unknown olm session: {}:{}", sender_key, id); continue; + } mtx::crypto::BinaryBuf text; diff --git a/src/Olm.h b/src/Olm.h index d356cb55..8479f4f2 100644 --- a/src/Olm.h +++ b/src/Olm.h @@ -4,8 +4,6 @@ #pragma once -#include - #include #include #include diff --git a/src/RegisterPage.cpp b/src/RegisterPage.cpp index 5c5545ec..1588d07d 100644 --- a/src/RegisterPage.cpp +++ b/src/RegisterPage.cpp @@ -11,6 +11,7 @@ #include #include +#include #include "Config.h" #include "Logging.h" @@ -108,6 +109,10 @@ RegisterPage::RegisterPage(QWidget *parent) error_password_confirmation_label_->setWordWrap(true); error_password_confirmation_label_->hide(); + error_server_label_ = new QLabel(this); + error_server_label_->setWordWrap(true); + error_server_label_->hide(); + form_layout_->addWidget(username_input_, Qt::AlignHCenter); form_layout_->addWidget(error_username_label_, Qt::AlignHCenter); form_layout_->addWidget(password_input_, Qt::AlignHCenter); @@ -115,6 +120,7 @@ RegisterPage::RegisterPage(QWidget *parent) form_layout_->addWidget(password_confirmation_, Qt::AlignHCenter); form_layout_->addWidget(error_password_confirmation_label_, Qt::AlignHCenter); form_layout_->addWidget(server_input_, Qt::AlignHCenter); + form_layout_->addWidget(error_server_label_, Qt::AlignHCenter); button_layout_ = new QHBoxLayout(); button_layout_->setSpacing(0); @@ -140,6 +146,17 @@ RegisterPage::RegisterPage(QWidget *parent) top_layout_->addWidget(error_label_, 0, Qt::AlignHCenter); top_layout_->addStretch(1); + connect( + this, + &RegisterPage::versionErrorCb, + this, + [this](const QString &msg) { + error_server_label_->show(); + server_input_->setValid(false); + showError(error_server_label_, msg); + }, + Qt::QueuedConnection); + connect(back_button_, SIGNAL(clicked()), this, SLOT(onBackButtonClicked())); connect(register_button_, SIGNAL(clicked()), this, SLOT(onRegisterButtonClicked())); @@ -272,7 +289,7 @@ RegisterPage::RegisterPage(QWidget *parent) } // The server requires registration flows. - if (err->status_code == boost::beast::http::status::unauthorized) { + if (err->status_code == 401) { if (err->matrix_error.unauthorized.flows.empty()) { nhlog::net()->warn( "failed to retrieve registration flows: ({}) " @@ -351,10 +368,12 @@ RegisterPage::checkFields() error_username_label_->setText(""); error_password_label_->setText(""); error_password_confirmation_label_->setText(""); + error_server_label_->setText(""); error_username_label_->hide(); error_password_label_->hide(); error_password_confirmation_label_->hide(); + error_server_label_->hide(); password_confirmation_->setValid(true); server_input_->setValid(true); @@ -379,7 +398,8 @@ RegisterPage::checkFields() all_fields_good = false; } else if (server_input_->isModified() && (!server_input_->hasAcceptableInput() || server_input_->text().isEmpty())) { - showError(tr("Invalid server name")); + error_server_label_->show(); + showError(error_server_label_, tr("Invalid server name")); server_input_->setValid(false); all_fields_good = false; } @@ -406,51 +426,110 @@ RegisterPage::onRegisterButtonClicked() http::client()->set_server(server); http::client()->verify_certificates( !UserSettings::instance()->disableCertificateValidation()); - http::client()->registration( - username, - password, - [this, username, password](const mtx::responses::Register &res, + + http::client()->well_known( + [this, username, password](const mtx::responses::WellKnown &res, mtx::http::RequestErr err) { - if (!err) { - http::client()->set_user(res.user_id); - http::client()->set_access_token(res.access_token); - - emit registerOk(); - return; - } - - // The server requires registration flows. - if (err->status_code == boost::beast::http::status::unauthorized) { - if (err->matrix_error.unauthorized.flows.empty()) { - nhlog::net()->warn( - "failed to retrieve registration flows1: ({}) " - "{}", - static_cast(err->status_code), - err->matrix_error.error); - emit errorOccurred(); - emit registerErrorCb( - QString::fromStdString(err->matrix_error.error)); + if (err) { + if (err->status_code == 404) { + nhlog::net()->info("Autodiscovery: No .well-known."); + checkVersionAndRegister(username, password); return; } - emit registrationFlow( - username, password, err->matrix_error.unauthorized); + if (!err->parse_error.empty()) { + emit versionErrorCb(tr( + "Autodiscovery failed. Received malformed response.")); + nhlog::net()->error( + "Autodiscovery failed. Received malformed response."); + return; + } + + emit versionErrorCb(tr("Autodiscovery failed. Unknown error when " + "requesting .well-known.")); + nhlog::net()->error("Autodiscovery failed. Unknown error when " + "requesting .well-known. {} {}", + err->status_code, + err->error_code); return; } - nhlog::net()->error( - "failed to register: status_code ({}), matrix_error({})", - static_cast(err->status_code), - err->matrix_error.error); - - emit registerErrorCb(QString::fromStdString(err->matrix_error.error)); - emit errorOccurred(); + nhlog::net()->info("Autodiscovery: Discovered '" + + res.homeserver.base_url + "'"); + http::client()->set_server(res.homeserver.base_url); + checkVersionAndRegister(username, password); }); emit registering(); } } +void +RegisterPage::checkVersionAndRegister(const std::string &username, const std::string &password) +{ + http::client()->versions( + [this, username, password](const mtx::responses::Versions &, mtx::http::RequestErr err) { + if (err) { + if (err->status_code == 404) { + emit versionErrorCb(tr("The required endpoints were not found. " + "Possibly not a Matrix server.")); + return; + } + + if (!err->parse_error.empty()) { + emit versionErrorCb(tr("Received malformed response. Make sure " + "the homeserver domain is valid.")); + return; + } + + emit versionErrorCb(tr( + "An unknown error occured. Make sure the homeserver domain is valid.")); + return; + } + + http::client()->registration( + username, + password, + [this, username, password](const mtx::responses::Register &res, + mtx::http::RequestErr err) { + if (!err) { + http::client()->set_user(res.user_id); + http::client()->set_access_token(res.access_token); + + emit registerOk(); + return; + } + + // The server requires registration flows. + if (err->status_code == 401) { + if (err->matrix_error.unauthorized.flows.empty()) { + nhlog::net()->warn( + "failed to retrieve registration flows1: ({}) " + "{}", + static_cast(err->status_code), + err->matrix_error.error); + emit errorOccurred(); + emit registerErrorCb( + QString::fromStdString(err->matrix_error.error)); + return; + } + + emit registrationFlow( + username, password, err->matrix_error.unauthorized); + return; + } + + nhlog::net()->error( + "failed to register: status_code ({}), matrix_error({})", + static_cast(err->status_code), + err->matrix_error.error); + + emit registerErrorCb(QString::fromStdString(err->matrix_error.error)); + emit errorOccurred(); + }); + }); +} + void RegisterPage::paintEvent(QPaintEvent *) { diff --git a/src/RegisterPage.h b/src/RegisterPage.h index 2f05d04c..0e4a45d0 100644 --- a/src/RegisterPage.h +++ b/src/RegisterPage.h @@ -31,6 +31,10 @@ protected: signals: void backButtonClicked(); void errorOccurred(); + + //! Used to trigger the corresponding slot outside of the main thread. + void versionErrorCb(const QString &err); + void registering(); void registerOk(); void registerErrorCb(const QString &msg); @@ -52,6 +56,7 @@ private: bool checkOneField(QLabel *label, const TextField *t_field, const QString &msg); bool checkFields(); void showError(QLabel *label, const QString &msg); + void checkVersionAndRegister(const std::string &username, const std::string &password); QVBoxLayout *top_layout_; QHBoxLayout *back_layout_; @@ -63,6 +68,7 @@ private: QLabel *error_username_label_; QLabel *error_password_label_; QLabel *error_password_confirmation_label_; + QLabel *error_server_label_; FlatButton *back_button_; RaisedButton *register_button_; diff --git a/src/UserSettingsPage.cpp b/src/UserSettingsPage.cpp index 99560678..740b8979 100644 --- a/src/UserSettingsPage.cpp +++ b/src/UserSettingsPage.cpp @@ -64,10 +64,14 @@ void UserSettings::load(std::optional profile) { QSettings settings; - tray_ = settings.value("user/window/tray", false).toBool(); + tray_ = settings.value("user/window/tray", false).toBool(); + startInTray_ = settings.value("user/window/start_in_tray", false).toBool(); + + roomListWidth_ = settings.value("user/sidebar/room_list_width", -1).toInt(); + communityListWidth_ = settings.value("user/sidebar/community_list_width", -1).toInt(); + hasDesktopNotifications_ = settings.value("user/desktop_notifications", true).toBool(); hasAlertOnNotification_ = settings.value("user/alert_on_notification", false).toBool(); - startInTray_ = settings.value("user/window/start_in_tray", false).toBool(); groupView_ = settings.value("user/group_view", true).toBool(); hiddenTags_ = settings.value("user/hidden_tags", QStringList{}).toStringList(); buttonsInTimeline_ = settings.value("user/timeline/buttons", true).toBool(); @@ -175,10 +179,11 @@ UserSettings::setMobileMode(bool state) void UserSettings::setGroupView(bool state) { - if (groupView_ != state) - emit groupViewStateChanged(state); + if (groupView_ == state) + return; groupView_ = state; + emit groupViewStateChanged(state); save(); } @@ -248,6 +253,24 @@ UserSettings::setTimelineMaxWidth(int state) emit timelineMaxWidthChanged(state); save(); } +void +UserSettings::setCommunityListWidth(int state) +{ + if (state == communityListWidth_) + return; + communityListWidth_ = state; + emit communityListWidthChanged(state); + save(); +} +void +UserSettings::setRoomListWidth(int state) +{ + if (state == roomListWidth_) + return; + roomListWidth_ = state; + emit roomListWidthChanged(state); + save(); +} void UserSettings::setDesktopNotifications(bool state) @@ -571,6 +594,11 @@ UserSettings::save() settings.setValue("start_in_tray", startInTray_); settings.endGroup(); // window + settings.beginGroup("sidebar"); + settings.setValue("community_list_width", communityListWidth_); + settings.setValue("room_list_width", roomListWidth_); + settings.endGroup(); // window + settings.beginGroup("timeline"); settings.setValue("buttons", buttonsInTimeline_); settings.setValue("message_hover_highlight", messageHoverHighlight_); @@ -586,6 +614,7 @@ UserSettings::save() settings.setValue("mobile_mode", mobileMode_); settings.setValue("font_size", baseFontSize_); settings.setValue("typing_notifications", typingNotifications_); + settings.setValue("sort_by_unread", sortByImportance_); settings.setValue("minor_events", sortByImportance_); settings.setValue("read_receipts", readReceipts_); settings.setValue("group_view", groupView_); diff --git a/src/UserSettingsPage.h b/src/UserSettingsPage.h index 3ad0293b..acb08569 100644 --- a/src/UserSettingsPage.h +++ b/src/UserSettingsPage.h @@ -61,6 +61,10 @@ class UserSettings : public QObject NOTIFY privacyScreenTimeoutChanged) Q_PROPERTY(int timelineMaxWidth READ timelineMaxWidth WRITE setTimelineMaxWidth NOTIFY timelineMaxWidthChanged) + Q_PROPERTY( + int roomListWidth READ roomListWidth WRITE setRoomListWidth NOTIFY roomListWidthChanged) + Q_PROPERTY(int communityListWidth READ communityListWidth WRITE setCommunityListWidth NOTIFY + communityListWidthChanged) Q_PROPERTY(bool mobileMode READ mobileMode WRITE setMobileMode NOTIFY mobileModeChanged) Q_PROPERTY(double fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) Q_PROPERTY(QString font READ font WRITE setFontFamily NOTIFY fontChanged) @@ -129,6 +133,8 @@ public: void setSortByImportance(bool state); void setButtonsInTimeline(bool state); void setTimelineMaxWidth(int state); + void setCommunityListWidth(int state); + void setRoomListWidth(int state); void setDesktopNotifications(bool state); void setAlertOnNotification(bool state); void setAvatarCircles(bool state); @@ -178,6 +184,8 @@ public: return hasDesktopNotifications() || hasAlertOnNotification(); } int timelineMaxWidth() const { return timelineMaxWidth_; } + int communityListWidth() const { return communityListWidth_; } + int roomListWidth() const { return roomListWidth_; } double fontSize() const { return baseFontSize_; } QString font() const { return font_; } QString emojiFont() const @@ -227,6 +235,8 @@ signals: void privacyScreenChanged(bool state); void privacyScreenTimeoutChanged(int state); void timelineMaxWidthChanged(int state); + void roomListWidthChanged(int state); + void communityListWidthChanged(int state); void mobileModeChanged(bool mode); void fontSizeChanged(double state); void fontChanged(QString state); @@ -276,6 +286,8 @@ private: bool shareKeysWithTrustedUsers_; bool mobileMode_; int timelineMaxWidth_; + int roomListWidth_; + int communityListWidth_; double baseFontSize_; QString font_; QString emojiFont_; diff --git a/src/Utils.cpp b/src/Utils.cpp index c110aa18..562b94fd 100644 --- a/src/Utils.cpp +++ b/src/Utils.cpp @@ -679,11 +679,10 @@ utils::hashQString(const QString &input) return hash; } -QString -utils::generateContrastingHexColor(const QString &input, const QString &background) +QColor +utils::generateContrastingHexColor(const QString &input, const QColor &backgroundCol) { - const QColor backgroundCol(background); - const qreal backgroundLum = luminance(background); + const qreal backgroundLum = luminance(backgroundCol); // Create a color for the input auto hash = hashQString(input); diff --git a/src/Utils.h b/src/Utils.h index e976cf81..1d48e2c7 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -301,8 +301,8 @@ hashQString(const QString &input); //! Generate a color (matching #RRGGBB) that has an acceptable contrast to background that is based //! on the input string. -QString -generateContrastingHexColor(const QString &input, const QString &background); +QColor +generateContrastingHexColor(const QString &input, const QColor &background); //! Given two luminance values, compute the contrast ratio between them. qreal diff --git a/src/WebRTCSession.cpp b/src/WebRTCSession.cpp index 880a14a2..72330435 100644 --- a/src/WebRTCSession.cpp +++ b/src/WebRTCSession.cpp @@ -41,8 +41,7 @@ using webrtc::CallType; using webrtc::State; WebRTCSession::WebRTCSession() - : QObject() - , devices_(CallDevices::instance()) + : devices_(CallDevices::instance()) { qRegisterMetaType(); qmlRegisterUncreatableMetaObject( diff --git a/src/main.cpp b/src/main.cpp index fe1a9ee3..29e93d49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,15 +40,48 @@ QQmlDebuggingEnabler enabler; #endif -#if defined(Q_OS_LINUX) -#include +#if HAVE_BACKTRACE_SYMBOLS_FD #include +#include +#include +#include void stacktraceHandler(int signum) { std::signal(signum, SIG_DFL); - boost::stacktrace::safe_dump_to("./nheko-backtrace.dump"); + + // boost::stacktrace::safe_dump_to("./nheko-backtrace.dump"); + + // see + // https://stackoverflow.com/questions/77005/how-to-automatically-generate-a-stacktrace-when-my-program-crashes/77336#77336 + void *array[50]; + size_t size; + + // get void*'s for all entries on the stack + size = backtrace(array, 50); + + // print out all the frames to stderr + fprintf(stderr, "Error: signal %d:\n", signum); + backtrace_symbols_fd(array, size, STDERR_FILENO); + + int file = ::open("/tmp/nheko-crash.dump", + O_CREAT | O_WRONLY | O_TRUNC +#if defined(S_IWUSR) && defined(S_IRUSR) + , + S_IWUSR | S_IRUSR +#elif defined(S_IWRITE) && defined(S_IREAD) + , + S_IWRITE | S_IREAD +#endif + ); + if (file != -1) { + constexpr char header[] = "Error: signal\n"; + [[maybe_unused]] auto ret = write(file, header, std::size(header) - 1); + backtrace_symbols_fd(array, size, file); + close(file); + } + std::raise(SIGABRT); } diff --git a/src/timeline/CommunitiesModel.cpp b/src/timeline/CommunitiesModel.cpp index cedaacce..97bfa76d 100644 --- a/src/timeline/CommunitiesModel.cpp +++ b/src/timeline/CommunitiesModel.cpp @@ -21,6 +21,8 @@ CommunitiesModel::roleNames() const {DisplayName, "displayName"}, {Tooltip, "tooltip"}, {ChildrenHidden, "childrenHidden"}, + {Hidden, "hidden"}, + {Id, "id"}, }; } @@ -37,11 +39,28 @@ CommunitiesModel::data(const QModelIndex &index, int role) const return tr("Shows all rooms without filtering."); case CommunitiesModel::Roles::ChildrenHidden: return false; + case CommunitiesModel::Roles::Hidden: + return false; case CommunitiesModel::Roles::Id: return ""; } - } else if (index.row() - 1 < tags_.size()) { - auto tag = tags_.at(index.row() - 1); + } else if (index.row() - 1 < spaceOrder_.size()) { + auto id = spaceOrder_.at(index.row() - 1); + switch (role) { + case CommunitiesModel::Roles::AvatarUrl: + return QString::fromStdString(spaces_.at(id).avatar_url); + case CommunitiesModel::Roles::DisplayName: + case CommunitiesModel::Roles::Tooltip: + return QString::fromStdString(spaces_.at(id).name); + case CommunitiesModel::Roles::ChildrenHidden: + return true; + case CommunitiesModel::Roles::Hidden: + return hiddentTagIds_.contains("space:" + id); + case CommunitiesModel::Roles::Id: + return "space:" + id; + } + } else if (index.row() - 1 < tags_.size() + spaceOrder_.size()) { + auto tag = tags_.at(index.row() - 1 - spaceOrder_.size()); if (tag == "m.favourite") { switch (role) { case CommunitiesModel::Roles::AvatarUrl: @@ -54,7 +73,7 @@ CommunitiesModel::data(const QModelIndex &index, int role) const } else if (tag == "m.lowpriority") { switch (role) { case CommunitiesModel::Roles::AvatarUrl: - return QString(":/icons/icons/ui/star.png"); + return QString(":/icons/icons/ui/lowprio.png"); case CommunitiesModel::Roles::DisplayName: return tr("Low Priority"); case CommunitiesModel::Roles::Tooltip: @@ -74,15 +93,16 @@ CommunitiesModel::data(const QModelIndex &index, int role) const case CommunitiesModel::Roles::AvatarUrl: return QString(":/icons/icons/ui/tag.png"); case CommunitiesModel::Roles::DisplayName: - return tag.right(2); case CommunitiesModel::Roles::Tooltip: - return tag.right(2); + return tag.mid(2); } } switch (role) { + case CommunitiesModel::Roles::Hidden: + return hiddentTagIds_.contains("tag:" + tag); case CommunitiesModel::Roles::ChildrenHidden: - return UserSettings::instance()->hiddenTags().contains("tag:" + tag); + return true; case CommunitiesModel::Roles::Id: return "tag:" + tag; } @@ -93,22 +113,35 @@ CommunitiesModel::data(const QModelIndex &index, int role) const void CommunitiesModel::initializeSidebar() { + beginResetModel(); + tags_.clear(); + spaceOrder_.clear(); + spaces_.clear(); + std::set ts; - for (const auto &e : cache::roomInfo()) { - for (const auto &t : e.tags) { - if (t.find("u.") == 0 || t.find("m." == 0)) { - ts.insert(t); + std::vector tempSpaces; + auto infos = cache::roomInfo(); + for (auto it = infos.begin(); it != infos.end(); it++) { + if (it.value().is_space) { + spaceOrder_.push_back(it.key()); + spaces_[it.key()] = it.value(); + } else { + for (const auto &t : it.value().tags) { + if (t.find("u.") == 0 || t.find("m." == 0)) { + ts.insert(t); + } } } } - beginResetModel(); - tags_.clear(); for (const auto &t : ts) tags_.push_back(QString::fromStdString(t)); + + hiddentTagIds_ = UserSettings::instance()->hiddenTags(); endResetModel(); emit tagsChanged(); + emit hiddenTagsChanged(); } void @@ -117,6 +150,7 @@ CommunitiesModel::clear() beginResetModel(); tags_.clear(); endResetModel(); + resetCurrentTagId(); emit tagsChanged(); } @@ -133,6 +167,25 @@ CommunitiesModel::sync(const mtx::responses::Rooms &rooms) mtx::events::AccountDataEvent>(e)) { tagsUpdated = true; } + for (const auto &e : room.state.events) + if (std::holds_alternative< + mtx::events::StateEvent>(e) || + std::holds_alternative< + mtx::events::StateEvent>(e)) { + tagsUpdated = true; + } + for (const auto &e : room.timeline.events) + if (std::holds_alternative< + mtx::events::StateEvent>(e) || + std::holds_alternative< + mtx::events::StateEvent>(e)) { + tagsUpdated = true; + } + } + for (const auto &[roomid, room] : rooms.leave) { + (void)room; + if (spaceOrder_.contains(QString::fromStdString(roomid))) + tagsUpdated = true; } if (tagsUpdated) @@ -143,16 +196,51 @@ void CommunitiesModel::setCurrentTagId(QString tagId) { if (tagId.startsWith("tag:")) { - auto tag = tagId.remove(0, 4); + auto tag = tagId.mid(4); for (const auto &t : tags_) { if (t == tag) { this->currentTagId_ = tagId; - emit currentTagIdChanged(); + emit currentTagIdChanged(currentTagId_); + return; + } + } + } else if (tagId.startsWith("space:")) { + auto tag = tagId.mid(6); + for (const auto &t : spaceOrder_) { + if (t == tag) { + this->currentTagId_ = tagId; + emit currentTagIdChanged(currentTagId_); return; } } } this->currentTagId_ = ""; - emit currentTagIdChanged(); + emit currentTagIdChanged(currentTagId_); +} + +void +CommunitiesModel::toggleTagId(QString tagId) +{ + if (hiddentTagIds_.contains(tagId)) { + hiddentTagIds_.removeOne(tagId); + UserSettings::instance()->setHiddenTags(hiddentTagIds_); + } else { + hiddentTagIds_.push_back(tagId); + UserSettings::instance()->setHiddenTags(hiddentTagIds_); + } + + if (tagId.startsWith("tag:")) { + auto idx = tags_.indexOf(tagId.mid(4)); + if (idx != -1) + emit dataChanged(index(idx + 1 + spaceOrder_.size()), + index(idx + 1 + spaceOrder_.size()), + {Hidden}); + } else if (tagId.startsWith("space:")) { + auto idx = spaceOrder_.indexOf(tagId.mid(6)); + if (idx != -1) + emit dataChanged(index(idx + 1), index(idx + 1), {Hidden}); + } + + emit hiddenTagsChanged(); } diff --git a/src/timeline/CommunitiesModel.h b/src/timeline/CommunitiesModel.h index 3f6a2a4c..677581dc 100644 --- a/src/timeline/CommunitiesModel.h +++ b/src/timeline/CommunitiesModel.h @@ -11,12 +11,15 @@ #include +#include "CacheStructs.h" + class CommunitiesModel : public QAbstractListModel { Q_OBJECT Q_PROPERTY(QString currentTagId READ currentTagId WRITE setCurrentTagId NOTIFY currentTagIdChanged RESET resetCurrentTagId) Q_PROPERTY(QStringList tags READ tags NOTIFY tagsChanged) + Q_PROPERTY(QStringList tagsWithDefault READ tagsWithDefault NOTIFY tagsChanged) public: enum Roles @@ -25,6 +28,7 @@ public: DisplayName, Tooltip, ChildrenHidden, + Hidden, Id, }; @@ -33,7 +37,7 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override { (void)parent; - return 1 + tags_.size(); + return 1 + tags_.size() + spaceOrder_.size(); } QVariant data(const QModelIndex &index, int role) const override; @@ -46,15 +50,29 @@ public slots: void resetCurrentTagId() { currentTagId_.clear(); - emit currentTagIdChanged(); + emit currentTagIdChanged(currentTagId_); } QStringList tags() const { return tags_; } + QStringList tagsWithDefault() const + { + QStringList tagsWD = tags_; + tagsWD.prepend("m.lowpriority"); + tagsWD.prepend("m.favourite"); + tagsWD.removeOne("m.server_notice"); + tagsWD.removeDuplicates(); + return tagsWD; + } + void toggleTagId(QString tagId); signals: - void currentTagIdChanged(); + void currentTagIdChanged(QString tagId); + void hiddenTagsChanged(); void tagsChanged(); private: QStringList tags_; QString currentTagId_; + QStringList hiddentTagIds_; + QStringList spaceOrder_; + std::map spaces_; }; diff --git a/src/timeline/EventStore.cpp b/src/timeline/EventStore.cpp index 4a9f0fff..9a91ff79 100644 --- a/src/timeline/EventStore.cpp +++ b/src/timeline/EventStore.cpp @@ -185,6 +185,48 @@ EventStore::EventStore(std::string room_id, QObject *) [this](std::string txn_id, std::string event_id) { nhlog::ui()->debug("sent {}", txn_id); + // Replace the event_id in pending edits/replies/redactions with the actual + // event_id of this event. This allows one to edit and reply to events that are + // currently pending. + + // FIXME (introduced by balsoft): this doesn't work for encrypted events, but + // allegedly it's hard to fix so I'll leave my first contribution at that + for (auto related_event_id : cache::client()->relatedEvents(room_id_, txn_id)) { + if (cache::client()->getEvent(room_id_, related_event_id)) { + auto related_event = + cache::client()->getEvent(room_id_, related_event_id).value(); + auto relations = mtx::accessors::relations(related_event.data); + + // Replace the blockquote in fallback reply + auto related_text = + std::get_if>( + &related_event.data); + if (related_text && relations.reply_to() == txn_id) { + size_t index = + related_text->content.formatted_body.find(txn_id); + if (index != std::string::npos) { + related_text->content.formatted_body.replace( + index, event_id.length(), event_id); + } + } + + for (mtx::common::Relation &rel : relations.relations) { + if (rel.event_id == txn_id) + rel.event_id = event_id; + } + + mtx::accessors::set_relations(related_event.data, relations); + + cache::client()->replaceEvent( + room_id_, related_event_id, related_event); + + auto idx = idToIndex(related_event_id); + + events_by_id_.remove({room_id_, related_event_id}); + events_.remove({room_id_, toInternalIdx(*idx)}); + } + } + http::client()->read_event( room_id_, event_id, [this, event_id](mtx::http::RequestErr err) { if (err) { @@ -193,6 +235,11 @@ EventStore::EventStore(std::string room_id, QObject *) } }); + auto idx = idToIndex(event_id); + + if (idx) + emit dataChanged(*idx, *idx); + cache::client()->removePendingStatus(room_id_, txn_id); this->current_txn = ""; this->current_txn_error_count = 0; @@ -628,6 +675,9 @@ EventStore::decryptEvent(const IdIndex &idx, index.room_id, index.session_id, e.sender); + // we may not want to request keys during initial sync and such + if (suppressKeyRequests) + break; // TODO: Check if this actually works and look in key backup auto copy = e; copy.room_id = room_id_; @@ -769,6 +819,18 @@ EventStore::decryptEvent(const IdIndex &idx, return asCacheEntry(std::move(decryptionResult.event.value())); } +void +EventStore::enableKeyRequests(bool suppressKeyRequests_) +{ + if (!suppressKeyRequests_) { + for (const auto &key : decryptedEvents_.keys()) + if (key.room == this->room_id_) + decryptedEvents_.remove(key); + suppressKeyRequests = false; + } else + suppressKeyRequests = true; +} + mtx::events::collections::TimelineEvents * EventStore::get(std::string id, std::string_view related_to, bool decrypt, bool resolve_edits) { diff --git a/src/timeline/EventStore.h b/src/timeline/EventStore.h index d9bb86cb..7c404102 100644 --- a/src/timeline/EventStore.h +++ b/src/timeline/EventStore.h @@ -115,6 +115,7 @@ public slots: void addPending(mtx::events::collections::TimelineEvents event); void receivedSessionKey(const std::string &session_id); void clearTimeline(); + void enableKeyRequests(bool suppressKeyRequests_); private: std::vector edits(const std::string &event_id); @@ -142,4 +143,5 @@ private: std::string current_txn; int current_txn_error_count = 0; bool noMoreMessages = false; + bool suppressKeyRequests = true; }; diff --git a/src/timeline/InputBar.cpp b/src/timeline/InputBar.cpp index c309daab..b0747a7c 100644 --- a/src/timeline/InputBar.cpp +++ b/src/timeline/InputBar.cpp @@ -296,7 +296,7 @@ InputBar::message(QString msg, MarkdownOverride useMarkdown, bool rainbowify) firstLine = false; body = QString("> <%1> %2\n").arg(related.quoted_user).arg(line); } else { - body = QString("%1\n> %2\n").arg(body).arg(line); + body += QString("> %1\n").arg(line); } } diff --git a/src/timeline/RoomlistModel.cpp b/src/timeline/RoomlistModel.cpp index 4dd44b30..87940948 100644 --- a/src/timeline/RoomlistModel.cpp +++ b/src/timeline/RoomlistModel.cpp @@ -33,6 +33,27 @@ RoomlistModel::RoomlistModel(TimelineViewManager *parent) &RoomlistModel::totalUnreadMessageCountUpdated, ChatPage::instance(), &ChatPage::unreadMessages); + + connect( + this, + &RoomlistModel::fetchedPreview, + this, + [this](QString roomid, RoomInfo info) { + if (this->previewedRooms.contains(roomid)) { + this->previewedRooms.insert(roomid, std::move(info)); + auto idx = this->roomidToIndex(roomid); + emit dataChanged(index(idx), + index(idx), + { + Roles::RoomName, + Roles::AvatarUrl, + Roles::IsSpace, + Roles::IsPreviewFetched, + Qt::DisplayRole, + }); + } + }, + Qt::QueuedConnection); } QHash @@ -51,6 +72,7 @@ RoomlistModel::roleNames() const {IsInvite, "isInvite"}, {IsSpace, "isSpace"}, {Tags, "tags"}, + {ParentSpaces, "parentSpaces"}, }; } @@ -60,6 +82,16 @@ RoomlistModel::data(const QModelIndex &index, int role) const if (index.row() >= 0 && static_cast(index.row()) < roomids.size()) { auto roomid = roomids.at(index.row()); + if (role == Roles::ParentSpaces) { + auto parents = cache::client()->getParentRoomIds(roomid.toStdString()); + QStringList list; + for (const auto &t : parents) + list.push_back(QString::fromStdString(t)); + return list; + } else if (role == Roles::RoomId) { + return roomid; + } + if (models.contains(roomid)) { auto room = models.value(roomid); switch (role) { @@ -67,8 +99,6 @@ RoomlistModel::data(const QModelIndex &index, int role) const return room->roomAvatarUrl(); case Roles::RoomName: return room->plainRoomName(); - case Roles::RoomId: - return room->roomId(); case Roles::LastMessage: return room->lastMessage().body; case Roles::Time: @@ -84,7 +114,10 @@ RoomlistModel::data(const QModelIndex &index, int role) const case Roles::NotificationCount: return room->notificationCount(); case Roles::IsInvite: + return false; case Roles::IsSpace: + return room->isSpace(); + case Roles::IsPreview: return false; case Roles::Tags: { auto info = cache::singleRoomInfo(roomid.toStdString()); @@ -103,14 +136,12 @@ RoomlistModel::data(const QModelIndex &index, int role) const return QString::fromStdString(room.avatar_url); case Roles::RoomName: return QString::fromStdString(room.name); - case Roles::RoomId: - return roomid; case Roles::LastMessage: - return room.msgInfo.body; + return QString(); case Roles::Time: - return room.msgInfo.descriptiveTime; + return QString(); case Roles::Timestamp: - return QVariant(static_cast(room.msgInfo.timestamp)); + return QVariant(static_cast(0)); case Roles::HasUnreadMessages: case Roles::HasLoudNotification: return false; @@ -120,13 +151,77 @@ RoomlistModel::data(const QModelIndex &index, int role) const return true; case Roles::IsSpace: return false; + case Roles::IsPreview: + return false; + case Roles::Tags: + return QStringList(); + default: + return {}; + } + } else if (previewedRooms.contains(roomid) && + previewedRooms.value(roomid).has_value()) { + auto room = previewedRooms.value(roomid).value(); + switch (role) { + case Roles::AvatarUrl: + return QString::fromStdString(room.avatar_url); + case Roles::RoomName: + return QString::fromStdString(room.name); + case Roles::LastMessage: + return tr("Previewing this room"); + case Roles::Time: + return QString(); + case Roles::Timestamp: + return QVariant(static_cast(0)); + case Roles::HasUnreadMessages: + case Roles::HasLoudNotification: + return false; + case Roles::NotificationCount: + return 0; + case Roles::IsInvite: + return false; + case Roles::IsSpace: + return room.is_space; + case Roles::IsPreview: + return true; + case Roles::IsPreviewFetched: + return true; case Roles::Tags: return QStringList(); default: return {}; } } else { - return {}; + if (role == Roles::IsPreview) + return true; + else if (role == Roles::IsPreviewFetched) + return false; + + fetchPreview(roomid); + switch (role) { + case Roles::AvatarUrl: + return QString(); + case Roles::RoomName: + return tr("No preview available"); + case Roles::LastMessage: + return QString(); + case Roles::Time: + return QString(); + case Roles::Timestamp: + return QVariant(static_cast(0)); + case Roles::HasUnreadMessages: + case Roles::HasLoudNotification: + return false; + case Roles::NotificationCount: + return 0; + case Roles::IsInvite: + return false; + case Roles::IsSpace: + return false; + case Roles::Tags: + return QStringList(); + default: + return {}; + } } } else { return {}; @@ -230,25 +325,111 @@ RoomlistModel::addRoom(const QString &room_id, bool suppressInsertNotification) newRoom->updateLastMessage(); - bool wasInvite = invites.contains(room_id); - if (!suppressInsertNotification && !wasInvite) - beginInsertRows(QModelIndex(), (int)roomids.size(), (int)roomids.size()); + std::vector previewsToAdd; + if (newRoom->isSpace()) { + auto childs = cache::client()->getChildRoomIds(room_id.toStdString()); + for (const auto &c : childs) { + auto id = QString::fromStdString(c); + if (!(models.contains(id) || invites.contains(id) || + previewedRooms.contains(id))) { + previewsToAdd.push_back(std::move(id)); + } + } + } + + bool wasInvite = invites.contains(room_id); + bool wasPreview = previewedRooms.contains(room_id); + if (!suppressInsertNotification && + ((!wasInvite && !wasPreview) || !previewedRooms.empty())) + // if the old room was already in the list, don't add it. Also add all + // previews at the same time. + beginInsertRows(QModelIndex(), + (int)roomids.size(), + (int)(roomids.size() + previewsToAdd.size() - + ((wasInvite || wasPreview) ? 0 : 1))); models.insert(room_id, std::move(newRoom)); - if (wasInvite) { auto idx = roomidToIndex(room_id); invites.remove(room_id); emit dataChanged(index(idx), index(idx)); + } else if (wasPreview) { + auto idx = roomidToIndex(room_id); + previewedRooms.remove(room_id); + emit dataChanged(index(idx), index(idx)); } else { roomids.push_back(room_id); } + for (auto p : previewsToAdd) { + previewedRooms.insert(p, std::nullopt); + roomids.push_back(std::move(p)); + } + if (!suppressInsertNotification && !wasInvite) endInsertRows(); } } +void +RoomlistModel::fetchPreview(QString roomid_) const +{ + std::string roomid = roomid_.toStdString(); + http::client()->get_state_event( + roomid, + "", + [this, roomid](const mtx::events::state::Create &c, mtx::http::RequestErr err) { + bool is_space = false; + if (!err) { + is_space = c.type == mtx::events::state::room_type::space; + } + + http::client()->get_state_event( + roomid, + "", + [this, roomid, is_space](const mtx::events::state::Avatar &a, + mtx::http::RequestErr) { + auto avatar_url = a.url; + + http::client()->get_state_event( + roomid, + "", + [this, roomid, avatar_url, is_space]( + const mtx::events::state::Topic &t, mtx::http::RequestErr) { + auto topic = t.topic; + http::client()->get_state_event( + roomid, + "", + [this, roomid, topic, avatar_url, is_space]( + const mtx::events::state::Name &n, + mtx::http::RequestErr err) { + if (err) { + nhlog::net()->warn( + "Failed to fetch name event to " + "create preview for {}", + roomid); + } + + // don't even add a preview, if we got not a single + // response + if (n.name.empty() && avatar_url.empty() && + topic.empty()) + return; + + RoomInfo info{}; + info.name = n.name; + info.is_space = is_space; + info.avatar_url = avatar_url; + info.topic = topic; + + const_cast(this)->fetchedPreview( + QString::fromStdString(roomid), info); + }); + }); + }); + }); +} + void RoomlistModel::sync(const mtx::responses::Rooms &rooms) { @@ -324,6 +505,7 @@ RoomlistModel::initializeRooms() models.clear(); roomids.clear(); invites.clear(); + currentRoom_ = nullptr; invites = cache::client()->invites(); for (const auto &id : invites.keys()) @@ -407,11 +589,15 @@ RoomlistModel::setCurrentRoom(QString roomid) namespace { enum NotificationImportance : short { - ImportanceDisabled = -1, + ImportanceDisabled = -3, + NoPreview = -2, + Preview = -1, AllEventsRead = 0, NewMessage = 1, NewMentions = 2, - Invite = 3 + Invite = 3, + SubSpace = 4, + CurrentSpace = 5, }; } @@ -421,7 +607,18 @@ FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const // Returns the degree of importance of the unread messages in the room. // If sorting by importance is disabled in settings, this only ever // returns ImportanceDisabled or Invite - if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) { + if (sourceModel()->data(idx, RoomlistModel::IsSpace).toBool()) { + if (filterType == FilterBy::Space && + filterStr == sourceModel()->data(idx, RoomlistModel::RoomId).toString()) + return CurrentSpace; + else + return SubSpace; + } else if (sourceModel()->data(idx, RoomlistModel::IsPreview).toBool()) { + if (sourceModel()->data(idx, RoomlistModel::IsPreviewFetched).toBool()) + return Preview; + else + return NoPreview; + } else if (sourceModel()->data(idx, RoomlistModel::IsInvite).toBool()) { return Invite; } else if (!this->sortByImportance) { return ImportanceDisabled; @@ -433,6 +630,7 @@ FilteredRoomlistModel::calculateImportance(const QModelIndex &idx) const return AllEventsRead; } } + bool FilteredRoomlistModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { @@ -485,6 +683,140 @@ FilteredRoomlistModel::FilteredRoomlistModel(RoomlistModel *model, QObject *pare sort(0); } +void +FilteredRoomlistModel::updateHiddenTagsAndSpaces() +{ + hiddenTags.clear(); + hiddenSpaces.clear(); + for (const auto &t : UserSettings::instance()->hiddenTags()) { + if (t.startsWith("tag:")) + hiddenTags.push_back(t.mid(4)); + else if (t.startsWith("space:")) + hiddenSpaces.push_back(t.mid(6)); + } + + invalidateFilter(); +} + +bool +FilteredRoomlistModel::filterAcceptsRow(int sourceRow, const QModelIndex &) const +{ + if (filterType == FilterBy::Nothing) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview) + .toBool()) { + return false; + } + + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; + } + + if (!hiddenTags.empty()) { + auto tags = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + for (const auto &t : tags) + if (hiddenTags.contains(t)) + return false; + } + + if (!hiddenSpaces.empty()) { + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; + } + + return true; + } else if (filterType == FilterBy::Tag) { + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsPreview) + .toBool()) { + return false; + } + + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool()) { + return false; + } + + auto tags = sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + if (!tags.contains(filterStr)) + return false; + + if (!hiddenTags.empty()) { + for (const auto &t : tags) + if (t != filterStr && hiddenTags.contains(t)) + return false; + } + + if (!hiddenSpaces.empty()) { + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; + } + + return true; + } else if (filterType == FilterBy::Space) { + if (filterStr == sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::RoomId) + .toString()) + return true; + + auto parents = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::ParentSpaces) + .toStringList(); + + if (!parents.contains(filterStr)) + return false; + + if (!hiddenTags.empty()) { + auto tags = + sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::Tags) + .toStringList(); + + for (const auto &t : tags) + if (hiddenTags.contains(t)) + return false; + } + + if (!hiddenSpaces.empty()) { + for (const auto &t : parents) + if (hiddenSpaces.contains(t)) + return false; + } + + if (sourceModel() + ->data(sourceModel()->index(sourceRow, 0), RoomlistModel::IsSpace) + .toBool() && + !parents.contains(filterStr)) { + return false; + } + + return true; + } else { + return true; + } +} + void FilteredRoomlistModel::toggleTag(QString roomid, QString tag, bool on) { @@ -532,7 +864,7 @@ FilteredRoomlistModel::previousRoom() if (r) { int idx = roomidToIndex(r->roomId()); idx--; - if (idx > 0) { + if (idx >= 0) { setCurrentRoom( data(index(idx, 0), RoomlistModel::Roles::RoomId).toString()); } diff --git a/src/timeline/RoomlistModel.h b/src/timeline/RoomlistModel.h index 7ee0419f..2005c35e 100644 --- a/src/timeline/RoomlistModel.h +++ b/src/timeline/RoomlistModel.h @@ -37,7 +37,10 @@ public: NotificationCount, IsInvite, IsSpace, + IsPreview, + IsPreviewFetched, Tags, + ParentSpaces, }; RoomlistModel(TimelineViewManager *parent = nullptr); @@ -86,15 +89,18 @@ private slots: signals: void totalUnreadMessageCountUpdated(int unreadMessages); void currentRoomChanged(); + void fetchedPreview(QString roomid, RoomInfo info); private: void addRoom(const QString &room_id, bool suppressInsertNotification = false); + void fetchPreview(QString roomid) const; TimelineViewManager *manager = nullptr; std::vector roomids; QHash invites; QHash> models; std::map roomReadStatus; + QHash> previewedRooms; QSharedPointer currentRoom_; @@ -109,6 +115,7 @@ class FilteredRoomlistModel : public QSortFilterProxyModel public: FilteredRoomlistModel(RoomlistModel *model, QObject *parent = nullptr); bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; + bool filterAcceptsRow(int sourceRow, const QModelIndex &) const override; public slots: int roomidToIndex(QString roomid) @@ -128,6 +135,24 @@ public slots: void nextRoom(); void previousRoom(); + void updateFilterTag(QString tagId) + { + if (tagId.startsWith("tag:")) { + filterType = FilterBy::Tag; + filterStr = tagId.mid(4); + } else if (tagId.startsWith("space:")) { + filterType = FilterBy::Space; + filterStr = tagId.mid(6); + } else { + filterType = FilterBy::Nothing; + filterStr.clear(); + } + + invalidateFilter(); + } + + void updateHiddenTagsAndSpaces(); + signals: void currentRoomChanged(); @@ -135,4 +160,14 @@ private: short int calculateImportance(const QModelIndex &idx) const; RoomlistModel *roomlistmodel; bool sortByImportance = true; + + enum class FilterBy + { + Tag, + Space, + Nothing, + }; + QString filterStr = ""; + FilterBy filterType = FilterBy::Nothing; + QStringList hiddenTags, hiddenSpaces; }; diff --git a/src/timeline/TimelineModel.cpp b/src/timeline/TimelineModel.cpp index f29f929e..caa40353 100644 --- a/src/timeline/TimelineModel.cpp +++ b/src/timeline/TimelineModel.cpp @@ -320,6 +320,10 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj { lastMessage_.timestamp = 0; + if (auto create = + cache::client()->getStateEvent(room_id.toStdString())) + this->isSpace_ = create->content.type == mtx::events::state::room_type::space; + connect( this, &TimelineModel::redactionFailed, @@ -376,6 +380,27 @@ TimelineModel::TimelineModel(TimelineViewManager *manager, QString room_id, QObj this->updateFlowEventId(event_id); }); + // When a message is sent, check if the current edit/reply relates to that message, + // and update the event_id so that it points to the sent message and not the pending one. + connect(&events, + &EventStore::messageSent, + this, + [this](std::string txn_id, std::string event_id) { + if (edit_.toStdString() == txn_id) { + edit_ = QString::fromStdString(event_id); + emit editChanged(edit_); + } + if (reply_.toStdString() == txn_id) { + reply_ = QString::fromStdString(event_id); + emit replyChanged(reply_); + } + }); + + connect(manager_, + &TimelineViewManager::initialSyncChanged, + &events, + &EventStore::enableKeyRequests); + showEventTimer.callOnTimeout(this, &TimelineModel::scrollTimerEvent); } @@ -507,6 +532,10 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r const static QRegularExpression matchImgUri( "(]*)src=\"mxc://([^\"]*)\"([^>]*>)"); formattedBody_.replace(matchImgUri, "\\1 src=\"image://mxcImage/\\2\"\\3"); + // Same regex but for single quotes around the src + const static QRegularExpression matchImgUri2( + "(]*)src=\'mxc://([^\']*)\'([^>]*>)"); + formattedBody_.replace(matchImgUri2, "\\1 src=\"image://mxcImage/\\2\"\\3"); const static QRegularExpression matchEmoticonHeight( "(]*)height=\"([^\"]*)\"([^>]*>)"); formattedBody_.replace(matchEmoticonHeight, @@ -568,10 +597,8 @@ TimelineModel::data(const mtx::events::collections::TimelineEvents &event, int r case IsEdited: return QVariant(relations(event).replaces().has_value()); case IsEditable: - return QVariant(!is_state_event(event) && - mtx::accessors::sender(event) == - http::client()->user_id().to_string() && - !event_id(event).empty() && event_id(event).front() == '$'); + return QVariant(!is_state_event(event) && mtx::accessors::sender(event) == + http::client()->user_id().to_string()); case IsEncrypted: { auto id = event_id(event); auto encrypted_event = events.get(id, "", false); @@ -757,6 +784,7 @@ TimelineModel::syncState(const mtx::responses::State &s) } else if (std::holds_alternative>(e)) { emit roomAvatarUrlChanged(); emit roomNameChanged(); + emit roomMemberCountChanged(); } } } @@ -813,6 +841,7 @@ TimelineModel::addEvents(const mtx::responses::Timeline &timeline) } else if (std::holds_alternative>(e)) { emit roomAvatarUrlChanged(); emit roomNameChanged(); + emit roomMemberCountChanged(); } } updateLastMessage(); @@ -1787,7 +1816,8 @@ TimelineModel::formatMemberEvent(QString id) } if (event->content.reason != "") { - rendered += tr(" Reason: %1").arg(QString::fromStdString(event->content.reason)); + rendered += + " " + tr("Reason: %1").arg(QString::fromStdString(event->content.reason)); } return rendered; @@ -1796,9 +1826,6 @@ TimelineModel::formatMemberEvent(QString id) void TimelineModel::setEdit(QString newEdit) { - if (edit_.startsWith('m')) - return; - if (newEdit.isEmpty()) { resetEdit(); return; @@ -1921,3 +1948,9 @@ TimelineModel::roomTopic() const return utils::replaceEmoji(utils::linkifyMessage( QString::fromStdString(info[room_id_].topic).toHtmlEscaped())); } + +int +TimelineModel::roomMemberCount() const +{ + return (int)cache::client()->memberCount(room_id_.toStdString()); +} diff --git a/src/timeline/TimelineModel.h b/src/timeline/TimelineModel.h index 3ebbe120..3392d474 100644 --- a/src/timeline/TimelineModel.h +++ b/src/timeline/TimelineModel.h @@ -161,6 +161,8 @@ class TimelineModel : public QAbstractListModel Q_PROPERTY(QString roomName READ roomName NOTIFY roomNameChanged) Q_PROPERTY(QString roomAvatarUrl READ roomAvatarUrl NOTIFY roomAvatarUrlChanged) Q_PROPERTY(QString roomTopic READ roomTopic NOTIFY roomTopicChanged) + Q_PROPERTY(int roomMemberCount READ roomMemberCount NOTIFY roomMemberCountChanged) + Q_PROPERTY(bool isSpace READ isSpace CONSTANT) Q_PROPERTY(InputBar *input READ input CONSTANT) Q_PROPERTY(Permissions *permissions READ permissions NOTIFY permissionsChanged) @@ -262,6 +264,8 @@ public: RelatedInfo relatedInfo(QString id); DescInfo lastMessage() const { return lastMessage_; } + bool isSpace() const { return isSpace_; } + int roomMemberCount() const; public slots: void setCurrentIndex(int index); @@ -348,6 +352,7 @@ signals: void roomNameChanged(); void roomTopicChanged(); void roomAvatarUrlChanged(); + void roomMemberCountChanged(); void permissionsChanged(); void forwardToRoom(mtx::events::collections::TimelineEvents *e, QString roomId); @@ -366,9 +371,6 @@ private: QString room_id_; - bool decryptDescription = true; - bool m_paginationInProgress = false; - QString currentId, currentReadId; QString reply_, edit_; QString textBeforeEdit, replyBeforeEdit; @@ -388,6 +390,10 @@ private: friend struct SendMessageVisitor; int notification_count = 0, highlight_count = 0; + + bool decryptDescription = true; + bool m_paginationInProgress = false; + bool isSpace_ = false; }; template diff --git a/src/timeline/TimelineViewManager.cpp b/src/timeline/TimelineViewManager.cpp index faf56b85..a45294d1 100644 --- a/src/timeline/TimelineViewManager.cpp +++ b/src/timeline/TimelineViewManager.cpp @@ -107,8 +107,7 @@ QColor TimelineViewManager::userColor(QString id, QColor background) { if (!userColors.contains(id)) - userColors.insert( - id, QColor(utils::generateContrastingHexColor(id, background.name()))); + userColors.insert(id, QColor(utils::generateContrastingHexColor(id, background))); return userColors.value(id); } @@ -195,7 +194,17 @@ TimelineViewManager::TimelineViewManager(CallManager *callManager, ChatPage *par }); qmlRegisterSingletonType( "im.nheko", 1, 0, "Rooms", [](QQmlEngine *, QJSEngine *) -> QObject * { - return new FilteredRoomlistModel(self->rooms_); + auto ptr = new FilteredRoomlistModel(self->rooms_); + + connect(self->communities_, + &CommunitiesModel::currentTagIdChanged, + ptr, + &FilteredRoomlistModel::updateFilterTag); + connect(self->communities_, + &CommunitiesModel::hiddenTagsChanged, + ptr, + &FilteredRoomlistModel::updateHiddenTagsAndSpaces); + return ptr; }); qmlRegisterSingletonType( "im.nheko", 1, 0, "Communities", [](QQmlEngine *, QJSEngine *) -> QObject * { @@ -386,18 +395,17 @@ TimelineViewManager::openImageOverlayInternal(QString eventId, QImage img) imgDialog->showFullScreen(); auto room = rooms_->currentRoom(); - connect( - imgDialog, &dialogs::ImageOverlay::saving, room, [this, eventId, imgDialog, room]() { - // hide the overlay while presenting the save dialog for better - // cross platform support. - imgDialog->hide(); + connect(imgDialog, &dialogs::ImageOverlay::saving, room, [eventId, imgDialog, room]() { + // hide the overlay while presenting the save dialog for better + // cross platform support. + imgDialog->hide(); - if (!room->saveMedia(eventId)) { - imgDialog->show(); - } else { - imgDialog->close(); - } - }); + if (!room->saveMedia(eventId)) { + imgDialog->show(); + } else { + imgDialog->close(); + } + }); } void diff --git a/src/ui/RoomSettings.cpp b/src/ui/RoomSettings.cpp index 0bc8759e..f78ef09b 100644 --- a/src/ui/RoomSettings.cpp +++ b/src/ui/RoomSettings.cpp @@ -181,7 +181,7 @@ RoomSettings::RoomSettings(QString roomid, QObject *parent) roomid_.toStdString(), [this](const mtx::pushrules::PushRule &rule, mtx::http::RequestErr &err) { if (err) { - if (err->status_code == boost::beast::http::status::not_found) + if (err->status_code == 404) http::client()->get_pushrules( "global", "room", diff --git a/src/ui/Theme.cpp b/src/ui/Theme.cpp index 26119393..732a0443 100644 --- a/src/ui/Theme.cpp +++ b/src/ui/Theme.cpp @@ -47,7 +47,7 @@ Theme::paletteFromTheme(std::string_view theme) darkActive.setColor(QPalette::ToolTipBase, darkActive.base().color()); darkActive.setColor(QPalette::ToolTipText, darkActive.text().color()); darkActive.setColor(QPalette::Link, QColor("#38a3d8")); - darkActive.setColor(QPalette::ButtonText, "#727274"); + darkActive.setColor(QPalette::ButtonText, "#828284"); return darkActive; } else { return original; diff --git a/src/ui/UserProfile.cpp b/src/ui/UserProfile.cpp index da130242..3d9c4b6a 100644 --- a/src/ui/UserProfile.cpp +++ b/src/ui/UserProfile.cpp @@ -39,7 +39,8 @@ UserProfile::UserProfile(QString roomid, getGlobalProfileData(); } - if (!cache::client() || !cache::client()->isDatabaseReady()) + if (!cache::client() || !cache::client()->isDatabaseReady() || + !ChatPage::instance()->timelineManager()) return; connect(cache::client(), @@ -127,10 +128,7 @@ UserProfile::displayName() QString UserProfile::avatarUrl() { - return (isGlobalUserProfile() && globalAvatarUrl != "") - ? globalAvatarUrl - : cache::avatarUrl(roomid_, userid_); - ; + return isGlobalUserProfile() ? globalAvatarUrl : cache::avatarUrl(roomid_, userid_); } bool diff --git a/third_party/SingleApplication-3.3.0/.github/FUNDING.yml b/third_party/SingleApplication-3.3.0/.github/FUNDING.yml new file mode 100644 index 00000000..3ca4d97a --- /dev/null +++ b/third_party/SingleApplication-3.3.0/.github/FUNDING.yml @@ -0,0 +1 @@ +github: itay-grudev diff --git a/third_party/SingleApplication-3.3.0/.github/workflows/build-cmake.yml b/third_party/SingleApplication-3.3.0/.github/workflows/build-cmake.yml new file mode 100644 index 00000000..6344b504 --- /dev/null +++ b/third_party/SingleApplication-3.3.0/.github/workflows/build-cmake.yml @@ -0,0 +1,56 @@ +name: "CI: Build Test" + +on: [push, pull_request] + +jobs: + build: + + strategy: + matrix: + qt_version: [5.12.6, 5.13.2, 5.14.0, 5.15.0, 6.0.0] + platform: [ubuntu-20.04, windows-latest, macos-latest] + include: + - qt_version: 6.0.0 + additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6 + - platform: ubuntu-20.04 + CXXFLAGS: -Wall -Wextra -pedantic -Werror + - platform: macos-latest + CXXFLAGS: -Wall -Wextra -pedantic -Werror + - platform: windows-latest + CXXFLAGS: /W4 /WX + + runs-on: ${{ matrix.platform }} + env: + CXXFLAGS: ${{ matrix.CXXFLAGS }} + + steps: + - uses: actions/checkout@v2.3.4 + + - name: Install Qt + uses: jurplel/install-qt-action@v2.11.1 + with: + version: ${{ matrix.qt_version }} + + - name: cmake + run: cmake . ${{ matrix.additional_arguments }} + + - name: cmake build + run: cmake --build . + + - name: Build example - basic (cmake) + working-directory: examples/basic/ + run: | + cmake . ${{ matrix.additional_arguments }} + cmake --build . + + - name: Build example - calculator (cmake) + working-directory: examples/calculator/ + run: | + cmake . ${{ matrix.additional_arguments }} + cmake --build . + + - name: Build example - sending_arguments (cmake) + working-directory: examples/sending_arguments/ + run: | + cmake . ${{ matrix.additional_arguments }} + cmake --build . diff --git a/third_party/SingleApplication-3.2.0-dc8042b/.gitignore b/third_party/SingleApplication-3.3.0/.gitignore similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/.gitignore rename to third_party/SingleApplication-3.3.0/.gitignore diff --git a/third_party/SingleApplication-3.2.0-dc8042b/CHANGELOG.md b/third_party/SingleApplication-3.3.0/CHANGELOG.md similarity index 98% rename from third_party/SingleApplication-3.2.0-dc8042b/CHANGELOG.md rename to third_party/SingleApplication-3.3.0/CHANGELOG.md index e2ba290e..51669b90 100644 --- a/third_party/SingleApplication-3.2.0-dc8042b/CHANGELOG.md +++ b/third_party/SingleApplication-3.3.0/CHANGELOG.md @@ -3,6 +3,12 @@ Changelog If by accident I have forgotten to credit someone in the CHANGELOG, email me and I will fix it. + +__3.3.0__ +--------- + +* Fixed message fragmentation issue causing crashes and incorrectly and inconsistently received messages. - _Nils Jeisecke_ + __3.2.0__ --------- diff --git a/third_party/SingleApplication-3.2.0-dc8042b/CMakeLists.txt b/third_party/SingleApplication-3.3.0/CMakeLists.txt similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/CMakeLists.txt rename to third_party/SingleApplication-3.3.0/CMakeLists.txt diff --git a/third_party/SingleApplication-3.2.0-dc8042b/LICENSE b/third_party/SingleApplication-3.3.0/LICENSE similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/LICENSE rename to third_party/SingleApplication-3.3.0/LICENSE diff --git a/third_party/SingleApplication-3.2.0-dc8042b/README.md b/third_party/SingleApplication-3.3.0/README.md similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/README.md rename to third_party/SingleApplication-3.3.0/README.md diff --git a/third_party/SingleApplication-3.2.0-dc8042b/SingleApplication b/third_party/SingleApplication-3.3.0/SingleApplication similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/SingleApplication rename to third_party/SingleApplication-3.3.0/SingleApplication diff --git a/third_party/SingleApplication-3.2.0-dc8042b/Windows.md b/third_party/SingleApplication-3.3.0/Windows.md similarity index 100% rename from third_party/SingleApplication-3.2.0-dc8042b/Windows.md rename to third_party/SingleApplication-3.3.0/Windows.md diff --git a/third_party/SingleApplication-3.3.0/examples/basic/CMakeLists.txt b/third_party/SingleApplication-3.3.0/examples/basic/CMakeLists.txt new file mode 100644 index 00000000..c1429230 --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/basic/CMakeLists.txt @@ -0,0 +1,12 @@ +cmake_minimum_required(VERSION 3.7.0) + +project(basic LANGUAGES CXX) + +# SingleApplication base class +set(QAPPLICATION_CLASS QCoreApplication) +add_subdirectory(../.. SingleApplication) + +add_executable(basic main.cpp) + +target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) + diff --git a/third_party/SingleApplication-3.3.0/examples/basic/basic.pro b/third_party/SingleApplication-3.3.0/examples/basic/basic.pro new file mode 100755 index 00000000..b7af16cf --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/basic/basic.pro @@ -0,0 +1,5 @@ +# Single Application implementation +include(../../singleapplication.pri) +DEFINES += QAPPLICATION_CLASS=QCoreApplication + +SOURCES += main.cpp diff --git a/third_party/SingleApplication-3.3.0/examples/basic/main.cpp b/third_party/SingleApplication-3.3.0/examples/basic/main.cpp new file mode 100755 index 00000000..b2092c6d --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/basic/main.cpp @@ -0,0 +1,10 @@ +#include + +int main(int argc, char *argv[]) +{ + SingleApplication app( argc, argv ); + + qWarning() << "Started a new instance"; + + return app.exec(); +} diff --git a/third_party/SingleApplication-3.3.0/examples/calculator/CMakeLists.txt b/third_party/SingleApplication-3.3.0/examples/calculator/CMakeLists.txt new file mode 100644 index 00000000..82305f04 --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/calculator/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.7.0) + +project(calculator LANGUAGES CXX) + +set(CMAKE_AUTOMOC ON) + +# SingleApplication base class +set(QAPPLICATION_CLASS QApplication) +add_subdirectory(../.. SingleApplication) + +find_package(Qt${QT_DEFAULT_MAJOR_VERSION} COMPONENTS Core REQUIRED) + +add_executable(${PROJECT_NAME} + button.h + calculator.h + button.cpp + calculator.cpp + main.cpp +) + +target_link_libraries(${PROJECT_NAME} SingleApplication::SingleApplication) diff --git a/third_party/SingleApplication-3.3.0/examples/calculator/button.cpp b/third_party/SingleApplication-3.3.0/examples/calculator/button.cpp new file mode 100644 index 00000000..d6cca0a0 --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/calculator/button.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include "button.h" + +//! [0] +Button::Button(const QString &text, QWidget *parent) + : QToolButton(parent) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + setText(text); +} +//! [0] + +//! [1] +QSize Button::sizeHint() const +//! [1] //! [2] +{ + QSize size = QToolButton::sizeHint(); + size.rheight() += 20; + size.rwidth() = qMax(size.width(), size.height()); + return size; +} +//! [2] diff --git a/third_party/SingleApplication-3.3.0/examples/calculator/button.h b/third_party/SingleApplication-3.3.0/examples/calculator/button.h new file mode 100644 index 00000000..2c014c7b --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/calculator/button.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BUTTON_H +#define BUTTON_H + +#include + +//! [0] +class Button : public QToolButton +{ + Q_OBJECT + +public: + explicit Button(const QString &text, QWidget *parent = 0); + + QSize sizeHint() const Q_DECL_OVERRIDE; +}; +//! [0] + +#endif diff --git a/third_party/SingleApplication-3.3.0/examples/calculator/calculator.cpp b/third_party/SingleApplication-3.3.0/examples/calculator/calculator.cpp new file mode 100644 index 00000000..3d34c2a7 --- /dev/null +++ b/third_party/SingleApplication-3.3.0/examples/calculator/calculator.cpp @@ -0,0 +1,406 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "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. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** 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 +** OWNER 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." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include + +#include "button.h" +#include "calculator.h" + +//! [0] +Calculator::Calculator(QWidget *parent) + : QWidget(parent) +{ + sumInMemory = 0.0; + sumSoFar = 0.0; + factorSoFar = 0.0; + waitingForOperand = true; +//! [0] + +//! [1] + display = new QLineEdit("0"); +//! [1] //! [2] + display->setReadOnly(true); + display->setAlignment(Qt::AlignRight); + display->setMaxLength(15); + + QFont font = display->font(); + font.setPointSize(font.pointSize() + 8); + display->setFont(font); +//! [2] + +//! [4] + for (int i = 0; i < NumDigitButtons; ++i) { + digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked())); + } + + Button *pointButton = createButton(".", SLOT(pointClicked())); + Button *changeSignButton = createButton("\302\261", SLOT(changeSignClicked())); + + Button *backspaceButton = createButton("Backspace", SLOT(backspaceClicked())); + Button *clearButton = createButton("Clear", SLOT(clear())); + Button *clearAllButton = createButton("Clear All", SLOT(clearAll())); + + Button *clearMemoryButton = createButton("MC", SLOT(clearMemory())); + Button *readMemoryButton = createButton("MR", SLOT(readMemory())); + Button *setMemoryButton = createButton("MS", SLOT(setMemory())); + Button *addToMemoryButton = createButton("M+", SLOT(addToMemory())); + + Button *divisionButton = createButton("\303\267", SLOT(multiplicativeOperatorClicked())); + Button *timesButton = createButton("\303\227", SLOT(multiplicativeOperatorClicked())); + Button *minusButton = createButton("-", SLOT(additiveOperatorClicked())); + Button *plusButton = createButton("+", SLOT(additiveOperatorClicked())); + + Button *squareRootButton = createButton("Sqrt", SLOT(unaryOperatorClicked())); + Button *powerButton = createButton("x\302\262", SLOT(unaryOperatorClicked())); + Button *reciprocalButton = createButton("1/x", SLOT(unaryOperatorClicked())); + Button *equalButton = createButton("=", SLOT(equalClicked())); +//! [4] + +//! [5] + QGridLayout *mainLayout = new QGridLayout; +//! [5] //! [6] + mainLayout->setSizeConstraint(QLayout::SetFixedSize); + mainLayout->addWidget(display, 0, 0, 1, 6); + mainLayout->addWidget(backspaceButton, 1, 0, 1, 2); + mainLayout->addWidget(clearButton, 1, 2, 1, 2); + mainLayout->addWidget(clearAllButton, 1, 4, 1, 2); + + mainLayout->addWidget(clearMemoryButton, 2, 0); + mainLayout->addWidget(readMemoryButton, 3, 0); + mainLayout->addWidget(setMemoryButton, 4, 0); + mainLayout->addWidget(addToMemoryButton, 5, 0); + + for (int i = 1; i < NumDigitButtons; ++i) { + int row = ((9 - i) / 3) + 2; + int column = ((i - 1) % 3) + 1; + mainLayout->addWidget(digitButtons[i], row, column); + } + + mainLayout->addWidget(digitButtons[0], 5, 1); + mainLayout->addWidget(pointButton, 5, 2); + mainLayout->addWidget(changeSignButton, 5, 3); + + mainLayout->addWidget(divisionButton, 2, 4); + mainLayout->addWidget(timesButton, 3, 4); + mainLayout->addWidget(minusButton, 4, 4); + mainLayout->addWidget(plusButton, 5, 4); + + mainLayout->addWidget(squareRootButton, 2, 5); + mainLayout->addWidget(powerButton, 3, 5); + mainLayout->addWidget(reciprocalButton, 4, 5); + mainLayout->addWidget(equalButton, 5, 5); + setLayout(mainLayout); + + setWindowTitle("Calculator"); +} +//! [6] + +//! [7] +void Calculator::digitClicked() +{ + Button *clickedButton = qobject_cast