Compare commits

..

1 commit

Author SHA1 Message Date
Maxim Logaev 4f7809dd6c Added language change in settings
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-04-24 15:57:57 +03:00
35 changed files with 219 additions and 502 deletions

View file

@ -11,7 +11,7 @@ jobs:
- run: sudo apt-get update - run: sudo apt-get update
- run: sudo apt-get remove libunwind-14-dev - run: sudo apt-get remove libunwind-14-dev
- run: sudo apt-get install -y build-essential gettext cmake valac libgee-0.8-dev libsqlite3-dev libgtk-4-dev libnotify-dev libgpgme-dev libsoup2.4-dev libgcrypt20-dev libqrencode-dev libnice-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libsrtp2-dev libadwaita-1-dev libsignal-protocol-c-dev libcanberra-dev - run: sudo apt-get install -y build-essential gettext cmake valac libgee-0.8-dev libsqlite3-dev libgtk-4-dev libnotify-dev libgpgme-dev libsoup2.4-dev libgcrypt20-dev libqrencode-dev libnice-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libsrtp2-dev libadwaita-1-dev libsignal-protocol-c-dev libcanberra-dev
- run: ./configure --release --no-debug --with-tests --enable-plugin=notification-sound --prefix=/usr --without-webrtc - run: ./configure --release --no-debug --with-tests --enable-plugin=notification-sound --prefix=/usr --without-webrtc --enable-select-lang
- run: cmake --build build - run: cmake --build build
- run: cmake --build build --target=test - run: cmake --build build --target=test
- name: Build DEB-package - name: Build DEB-package
@ -41,7 +41,7 @@ jobs:
- run: sudo apt-get update - run: sudo apt-get update
- run: sudo apt-get remove libunwind-14-dev - run: sudo apt-get remove libunwind-14-dev
- run: sudo apt-get install -y build-essential gettext libadwaita-1-dev libcanberra-dev libgcrypt20-dev libgee-0.8-dev libgpgme-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgtk-4-dev libnice-dev libnotify-dev libqrencode-dev libsignal-protocol-c-dev libsoup2.4-dev libsqlite3-dev libsrtp2-dev meson valac - run: sudo apt-get install -y build-essential gettext libadwaita-1-dev libcanberra-dev libgcrypt20-dev libgee-0.8-dev libgpgme-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev libgtk-4-dev libnice-dev libnotify-dev libqrencode-dev libsignal-protocol-c-dev libsoup2.4-dev libsqlite3-dev libsrtp2-dev meson valac
- run: meson setup build -Duse-soup2=true -Dplugin-rtp-webrtc-audio-processing=disabled - run: meson setup build -Duse-soup2=true -Dplugin-rtp-webrtc-audio-processing=disabled -Dselect-lang=enabled
- run: meson compile -C build - run: meson compile -C build
- run: meson test -C build - run: meson test -C build
build-flatpak: build-flatpak:

View file

@ -14,6 +14,7 @@ include(CTest)
option(PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING "Use WebRTC audio processing" ON) option(PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING "Use WebRTC audio processing" ON)
option(WITH_WASAPI "Use wasapi instead of directsound on windows" ON) option(WITH_WASAPI "Use wasapi instead of directsound on windows" ON)
option(ENABLE_SELECT_LANG "Add language change to settings" OFF)
# https://gitlab.kitware.com/cmake/cmake/-/issues/19804 # https://gitlab.kitware.com/cmake/cmake/-/issues/19804
if (WIN32) if (WIN32)
@ -81,8 +82,6 @@ macro(set_path what val desc)
endif() endif()
endmacro(set_path) endmacro(set_path)
set(LOCALEDIR_NAME "share/locale")
string(REGEX REPLACE "^liblib" "lib" LIBDIR_NAME "lib${LIB_SUFFIX}") string(REGEX REPLACE "^liblib" "lib" LIBDIR_NAME "lib${LIB_SUFFIX}")
set_path(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Installation directory for architecture-independent files") set_path(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Installation directory for architecture-independent files")
set_path(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Installation directory for architecture-dependent files") set_path(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" "Installation directory for architecture-dependent files")
@ -96,7 +95,7 @@ set_path(SERVICE_FILE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/dbus-1/services" "Ins
set_path(ICON_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/icons" "Installation directory for icons") set_path(ICON_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/icons" "Installation directory for icons")
set_path(INCLUDE_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/include" "Installation directory for C header files") set_path(INCLUDE_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/include" "Installation directory for C header files")
set_path(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/${LIBDIR_NAME}" "Installation directory for object code libraries") set_path(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/${LIBDIR_NAME}" "Installation directory for object code libraries")
set_path(LOCALE_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/${LOCALEDIR_NAME}" "Installation directory for locale files") set_path(LOCALE_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/locale" "Installation directory for locale files")
set_path(PLUGIN_INSTALL_DIR "${LIB_INSTALL_DIR}/dino/plugins" "Installation directory for dino plugin object code files") set_path(PLUGIN_INSTALL_DIR "${LIB_INSTALL_DIR}/dino/plugins" "Installation directory for dino plugin object code files")
set_path(VAPI_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/vala/vapi" "Installation directory for Vala API files") set_path(VAPI_INSTALL_DIR "${SHARE_INSTALL_PREFIX}/vala/vapi" "Installation directory for Vala API files")
@ -197,7 +196,11 @@ endif (NOT NO_DEBUG)
if (WIN32) if (WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=1") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=1")
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} --define=_WIN32") set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} --define=_WIN32")
endif(WIN32) endif (WIN32)
if (ENABLE_SELECT_LANG)
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} --define=ENABLE_SELECT_LANG")
endif (ENABLE_SELECT_LANG)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

View file

@ -32,18 +32,16 @@ OS support
------------ ------------
* Linux (flatpaks are targeted for Ubuntu 22.04+) * Linux (flatpaks are targeted for Ubuntu 22.04+)
* Windows 10\11 * Windows 10\11
* MacOS via [brew](https://brew.sh/) (very experimental, see below) * MacOS via [brew](https://brew.sh/) (very experimental!)
Officially, we support only x86_64 architecture. Whilst you may be able to compile this code for ARM-based platforms (like Pinephone or MacOS), there's zero guarantees that it'll compile or function properly, as we don't have the hardware and the time to test it out. We only support 64 bit platforms.
Installation (prebuilt packages & AUR) Installation (prebuilt packages)
------------ ------------
Have a look at our [releases](https://github.com/mxlgv/dino/releases). Have a look at our [releases](https://github.com/mxlgv/dino/releases).
Windows installer is self-explanatory, and will place a shortcut on your desktop. Ignore the possible warning from Windows Defender: it's caused by the fact that installer does not have a digital signature. Windows installer is self-explanatory, and will place a shortcut on your desktop. Ignore the possible warning from Windows Defender: it's caused by the fact that installer does not have a digital signature.
Deb package is built and tested only for Ubuntu 22.04, but it may work on its derivatives as well, such as Pop!_OS or Linux Mint.
Flatpak is not present in Flathub yet, but you can install it manually. The commands below assume that you have "flatpak" package of your distro installed in your system. If it is not, please refer to https://flatpak.org/setup/ Flatpak is not present in Flathub yet, but you can install it manually. The commands below assume that you have "flatpak" package of your distro installed in your system. If it is not, please refer to https://flatpak.org/setup/
1) Download the .flatpak file from [releases](https://github.com/mxlgv/dino/releases) 1) Download the .flatpak file from [releases](https://github.com/mxlgv/dino/releases)
@ -51,7 +49,7 @@ Flatpak is not present in Flathub yet, but you can install it manually. The comm
``` ```
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
``` ```
3) Change the directory to the one you've downloaded the .flatpak to and run (you may have to change the file name in this command): 3) Change the directory to the one you've downloaded the .flatpak to and run:
``` ```
flatpak install ./im.dino.Dino.flatpak flatpak install ./im.dino.Dino.flatpak
``` ```
@ -66,18 +64,14 @@ Flatpak is not present in Flathub yet, but you can install it manually. The comm
Flatpak distribution is confirmed to be working on Arch Testing, Manjaro Stable, Void Linux and Linux Mint. Flatpak distribution is confirmed to be working on Arch Testing, Manjaro Stable, Void Linux and Linux Mint.
Arch Linux & Manjaro users may install `dino-plus-git` package from [AUR](https://aur.archlinux.org/packages/dino-plus-git) via any helper of their choice.
Build on Linux Build on Linux
----- -----
Make sure to install all [dependencies](https://github.com/dino/dino/wiki/Build#dependencies). Make sure to install all [dependencies](https://github.com/dino/dino/wiki/Build#dependencies).
./configure --release --no-debug --with-tests --enable-plugin=notification-sound --prefix=/usr ./configure
make make
build/dino build/dino
Additionally, you might need to install `gst-plugins-bad` and `webrtc-audio-processing` packages (or however they might be called in your distro), if you want to have noise cancelling and gain control. If you don't want that or your distro don't have that package, add "--without-webrtc" (without quotes) to the first command.
If you want to use `meson` build system, follow the next instructions: If you want to use `meson` build system, follow the next instructions:
meson setup build meson setup build
@ -97,6 +91,8 @@ If there is no `webrtcdsp` plugin in your system (check this by calling `gst-ins
* `-Dplugin-rtp-webrtc-audio-processing=disabled` for `meson`; * `-Dplugin-rtp-webrtc-audio-processing=disabled` for `meson`;
* `-DPLUGIN_RTP_WEBRTC_AUDIO_PROCESSING=OFF` for `cmake`. * `-DPLUGIN_RTP_WEBRTC_AUDIO_PROCESSING=OFF` for `cmake`.
In addition, there is a git version of this package for **Arch Linux** on [AUR](https://aur.archlinux.org/packages/dino-plus-git)
Build on Windows (x86_64) Build on Windows (x86_64)
------------ ------------
- Install and configure the [MSYS2](https://www.msys2.org/) package; - Install and configure the [MSYS2](https://www.msys2.org/) package;

View file

@ -21,13 +21,13 @@ fatal()
download_yolort() download_yolort()
{ {
file_name=yolort.zip file_name=cppwinrt-2.0.210122.3+windows-10.0.19041+yolort-835cd4e.zip
yolort_dir="$PROJ_DIR/plugins/windows-notification/yolort" yolort_dir="$PROJ_DIR/plugins/windows-notification/yolort"
rm -rf "$yolort_dir" rm -rf "$yolort_dir"
mkdir "$yolort_dir" mkdir "$yolort_dir"
curl -L -o "$file_name" "https://github.com/mxlgv/YoloRT/releases/download/dev1/$file_name" curl -L -o "$file_name" "https://github.com/LAGonauta/YoloRT/releases/download/v1.0.0/$file_name"
echo "c2727e390da7e842f66e0a4cf0a9f5d9dfb665115bb554152d98f108d322bbc1 $file_name" | sha256sum --check --status echo "675a6d943c97b4acdbfaa473f68d3241d1798b31a67b5529c8d29fc0176a1707 $file_name" | sha256sum --check --status
unzip -o "$file_name" -d "$yolort_dir" unzip -o "$file_name" -d "$yolort_dir"
rm -f "$file_name" rm -f "$file_name"
} }
@ -94,7 +94,7 @@ prepare()
configure_cmake() configure_cmake()
{ {
msg "Running configuration for Windows" msg "Running configuration for Windows"
./configure --program-prefix="$DIST_DIR" --no-debug --release --disable-fast-vapi --with-libsoup3 --with-tests ./configure --program-prefix="$DIST_DIR" --no-debug --release --disable-fast-vapi --with-libsoup3 --with-tests --enable-select-lang
msg "Configured!" msg "Configured!"
} }
@ -125,6 +125,7 @@ configure_meson()
meson setup ${cmd} --prefix "$DIST_DIR" \ meson setup ${cmd} --prefix "$DIST_DIR" \
-D crypto-backend=${encr} \ -D crypto-backend=${encr} \
-D plugin-ice=enabled \ -D plugin-ice=enabled \
-D select-lang=enabled \
$PROJ_DIR $BUILD_DIR $PROJ_DIR $BUILD_DIR
} }

5
configure vendored
View file

@ -2,6 +2,7 @@
OPTS=`getopt -o "h" --long \ OPTS=`getopt -o "h" --long \
help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsoup3,without-webrtcdsp,\ help,fetch-only,no-debug,disable-fast-vapi,with-tests,release,with-libsoup3,without-webrtcdsp,\
enable-select-lang,\
enable-plugin:,disable-plugin:,\ enable-plugin:,disable-plugin:,\
prefix:,program-prefix:,exec-prefix:,lib-suffix:,\ prefix:,program-prefix:,exec-prefix:,lib-suffix:,\
bindir:,libdir:,includedir:,datadir:,\ bindir:,libdir:,includedir:,datadir:,\
@ -18,6 +19,7 @@ DISABLED_PLUGINS=
BUILD_TESTS=no BUILD_TESTS=no
BUILD_TYPE=Debug BUILD_TYPE=Debug
DISABLE_FAST_VAPI= DISABLE_FAST_VAPI=
ENABLE_SELECT_LANG=no
LIB_SUFFIX= LIB_SUFFIX=
NO_DEBUG= NO_DEBUG=
USE_SOUP3= USE_SOUP3=
@ -52,6 +54,7 @@ Configuration:
builds (during development). builds (during development).
--fetch-only Only fetch the files required to run ./configure --fetch-only Only fetch the files required to run ./configure
without network access later and exit. without network access later and exit.
--enable-select-lang enable language switching for the settings menu
--no-debug Build without debug symbols --no-debug Build without debug symbols
--release Configure to build an optimized release version --release Configure to build an optimized release version
--with-libsoup3 Build with libsoup-3.0 --with-libsoup3 Build with libsoup-3.0
@ -113,6 +116,7 @@ while true; do
--with-libsoup3 ) USE_SOUP3=yes; shift ;; --with-libsoup3 ) USE_SOUP3=yes; shift ;;
--without-webrtcdsp ) PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING=no; shift ;; --without-webrtcdsp ) PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING=no; shift ;;
--disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;; --disable-fast-vapi ) DISABLE_FAST_VAPI=yes; shift ;;
--enable-select-lang) ENABLE_SELECT_LANG=yes; shift ;;
--no-debug ) NO_DEBUG=yes; shift ;; --no-debug ) NO_DEBUG=yes; shift ;;
--release ) BUILD_TYPE=RelWithDebInfo; shift ;; --release ) BUILD_TYPE=RelWithDebInfo; shift ;;
--with-tests ) BUILD_TESTS=yes; shift ;; --with-tests ) BUILD_TESTS=yes; shift ;;
@ -223,6 +227,7 @@ cmake -G "$cmake_type" \
-DINCLUDE_INSTALL_DIR="$INCLUDEDIR" \ -DINCLUDE_INSTALL_DIR="$INCLUDEDIR" \
-DLIB_INSTALL_DIR="$LIBDIR" \ -DLIB_INSTALL_DIR="$LIBDIR" \
-DPLUGIN_RTP_WEBRTC_AUDIO_PROCESSING="$PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING" \ -DPLUGIN_RTP_WEBRTC_AUDIO_PROCESSING="$PLUGIN_RTP_WEBRTC_AUDIO_PROCESSING" \
-DENABLE_SELECT_LANG="$ENABLE_SELECT_LANG" \
-Wno-dev \ -Wno-dev \
.. || exit 9 .. || exit 9

View file

@ -1,7 +1,7 @@
{ {
"id": "im.dino.Dino", "id": "im.dino.Dino",
"runtime": "org.gnome.Platform", "runtime": "org.gnome.Platform",
"runtime-version": "46", "runtime-version": "44",
"sdk": "org.gnome.Sdk", "sdk": "org.gnome.Sdk",
"command": "dino", "command": "dino",
"finish-args": [ "finish-args": [
@ -60,11 +60,7 @@
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"builddir": true, "builddir": true,
"config-opts": [ "config-opts": [
"-DSOUP_VERSION=3", "-DSOUP_VERSION=3"
"-DNO_DEBUG=yes",
"-DCMAKE_BUILD_TYPE=Release",
"-DENABLED_PLUGINS=notification-sound",
"-DPLUGIN_RTP_WEBRTC_AUDIO_PROCESSING=OFF"
], ],
"cleanup": [ "cleanup": [
"/include", "/include",

View file

@ -102,8 +102,7 @@ DEPENDS
${CMAKE_BINARY_DIR}/exports/dino_i18n.h ${CMAKE_BINARY_DIR}/exports/dino_i18n.h
) )
add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino" add_definitions(${VALA_CFLAGS} -DDINO_SYSTEM_PLUGIN_DIR="${PLUGIN_INSTALL_DIR}" -DDINO_SYSTEM_LIBDIR_NAME="${LIBDIR_NAME}" -DG_LOG_DOMAIN="libdino" -DDINO_VERSION=\"${PROJECT_VERSION}\")
-DDINO_VERSION=\"${PROJECT_VERSION}\" -DDINO_SYSTEM_LOCALEDIR_NAME="${LOCALEDIR_NAME}")
add_library(libdino SHARED ${LIBDINO_VALA_C} ${CMAKE_BINARY_DIR}/exports/dino_i18n.h) add_library(libdino SHARED ${LIBDINO_VALA_C} ${CMAKE_BINARY_DIR}/exports/dino_i18n.h)
add_dependencies(libdino dino-vapi) add_dependencies(libdino dino-vapi)
target_link_libraries(libdino xmpp-vala qlite ${LIBDINO_PACKAGES} m) target_link_libraries(libdino xmpp-vala qlite ${LIBDINO_PACKAGES} m)

View file

@ -80,7 +80,6 @@ sources = files(
sources += [version_vala] sources += [version_vala]
c_args = [ c_args = [
'-DDINO_SYSTEM_LIBDIR_NAME="@0@"'.format(get_option('libdir')), '-DDINO_SYSTEM_LIBDIR_NAME="@0@"'.format(get_option('libdir')),
'-DDINO_SYSTEM_LOCALEDIR_NAME="@0@"'.format(get_option('localedir')),
'-DDINO_SYSTEM_PLUGIN_DIR="@0@"'.format(get_option('prefix') / get_option('libdir') / get_option('plugindir')), '-DDINO_SYSTEM_PLUGIN_DIR="@0@"'.format(get_option('prefix') / get_option('libdir') / get_option('plugindir')),
'-DG_LOG_DOMAIN="libdino"', '-DG_LOG_DOMAIN="libdino"',
] ]

View file

@ -25,15 +25,19 @@ public interface Application : GLib.Application {
public abstract void handle_uri(string jid, string query, Gee.Map<string, string> options); public abstract void handle_uri(string jid, string query, Gee.Map<string, string> options);
public void init(bool default_dark_theme) throws Error { public void init() throws Error {
if (DirUtils.create_with_parents(get_storage_dir(), 0700) == -1) { if (DirUtils.create_with_parents(get_storage_dir(), 0700) == -1) {
throw new Error(-1, 0, "Could not create storage dir \"%s\": %s", get_storage_dir(), FileUtils.error_from_errno(errno).to_string()); throw new Error(-1, 0, "Could not create storage dir \"%s\": %s", get_storage_dir(), FileUtils.error_from_errno(errno).to_string());
} }
this.db = new Database(Path.build_filename(get_storage_dir(), "dino.db")); this.db = new Database(Path.build_filename(get_storage_dir(), "dino.db"));
this.settings = new Dino.Entities.Settings.from_db(db, default_dark_theme); this.settings = new Dino.Entities.Settings.from_db(db);
this.stream_interactor = new StreamInteractor(db); this.stream_interactor = new StreamInteractor(db);
#if ENABLE_SELECT_LANG
Environment.set_variable("LANGUAGE", settings.ui_language, true);
#endif
MessageProcessor.start(stream_interactor, db); MessageProcessor.start(stream_interactor, db);
MessageStorage.start(stream_interactor, db); MessageStorage.start(stream_interactor, db);
PresenceManager.start(stream_interactor); PresenceManager.start(stream_interactor);

View file

@ -4,7 +4,7 @@ public class Settings : Object {
private Database db; private Database db;
public Settings.from_db(Database db, bool default_dark_theme) { public Settings.from_db(Database db) {
this.db = db; this.db = db;
send_typing_ = col_to_bool_or_default("send_typing", true); send_typing_ = col_to_bool_or_default("send_typing", true);
@ -15,7 +15,7 @@ public class Settings : Object {
default_encryption = col_to_encryption_or_default("default_encryption", Encryption.UNKNOWN); default_encryption = col_to_encryption_or_default("default_encryption", Encryption.UNKNOWN);
send_button = col_to_bool_or_default("send_button", false); send_button = col_to_bool_or_default("send_button", false);
enter_newline = col_to_bool_or_default("enter_newline", false); enter_newline = col_to_bool_or_default("enter_newline", false);
dark_theme = col_to_bool_or_default("dark_theme", default_dark_theme); ui_language_ = col_to_string_or_default("ui_language", "en");
} }
private bool col_to_bool_or_default(string key, bool def) { private bool col_to_bool_or_default(string key, bool def) {
@ -29,6 +29,12 @@ public class Settings : Object {
return val != null ? Encryption.parse(val) : def; return val != null ? Encryption.parse(val) : def;
} }
private string col_to_string_or_default(string key, string def) {
var sval = db.settings.value;
string? val = db.settings.select({sval}).with(db.settings.key, "=", key)[sval];
return val != null ? val : def;
}
private bool send_typing_; private bool send_typing_;
public bool send_typing { public bool send_typing {
get { return send_typing_; } get { return send_typing_; }
@ -130,17 +136,16 @@ public class Settings : Object {
} }
} }
public signal void dark_theme_update(bool is_dark); private string ui_language_;
private bool dark_theme_; public string ui_language {
public bool dark_theme { get { return ui_language_; }
get { return dark_theme_; }
set { set {
string valstr = value.to_string();
db.settings.upsert() db.settings.upsert()
.value(db.settings.key, "dark_theme", true) .value(db.settings.key, "ui_language", true)
.value(db.settings.value, value.to_string()) .value(db.settings.value, valstr)
.perform(); .perform();
dark_theme_ = value; ui_language_ = value;
dark_theme_update(value);
} }
} }
} }

View file

@ -46,15 +46,6 @@ public class FileManager : StreamInteractionModule, Object {
return ret; return ret;
} }
private string sanitize_filename(string filename) {
#if _WIN32
GLib.Regex regex = new GLib.Regex("[<>:\"/\\|?*]");
#else
GLib.Regex regex = new GLib.Regex("[/]");
#endif
return regex.replace(filename, -1, 0, "_");
}
public async void send_file(File file, Conversation conversation) { public async void send_file(File file, Conversation conversation) {
FileTransfer file_transfer = new FileTransfer(); FileTransfer file_transfer = new FileTransfer();
file_transfer.account = conversation.account; file_transfer.account = conversation.account;
@ -252,7 +243,7 @@ public class FileManager : StreamInteractionModule, Object {
} }
// Save file // Save file
string filename = Random.next_int().to_string("%x") + "_" + sanitize_filename(file_transfer.file_name); string filename = Random.next_int().to_string("%x") + "_" + file_transfer.file_name;
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename)); File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION); OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION);
@ -341,7 +332,7 @@ public class FileManager : StreamInteractionModule, Object {
private async void save_file(FileTransfer file_transfer) throws FileSendError { private async void save_file(FileTransfer file_transfer) throws FileSendError {
try { try {
string filename = Random.next_int().to_string("%x") + "_" + sanitize_filename(file_transfer.file_name); string filename = Random.next_int().to_string("%x") + "_" + file_transfer.file_name;
File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename)); File file = File.new_for_path(Path.build_filename(get_storage_dir(), filename));
OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION); OutputStream os = file.create(FileCreateFlags.REPLACE_DESTINATION);
yield os.splice_async(file_transfer.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE|OutputStreamSpliceFlags.CLOSE_TARGET); yield os.splice_async(file_transfer.input_stream, OutputStreamSpliceFlags.CLOSE_SOURCE|OutputStreamSpliceFlags.CLOSE_TARGET);

View file

@ -6,7 +6,7 @@ namespace Dino {
public class Util { public class Util {
#if _WIN32 #if _WIN32
[CCode (cname = "ShellExecuteA", cheader_filename = "windows.h")] [CCode (cname = "ShellExecuteA", cheader_filename = "windows.h")]
private static extern int* ShellExecuteA(int* hwnd, string operation, string file, string parameters, string directory, int showCmd); private static extern int ShellExecuteA(int* hwnd, string operation, string file, string parameters, string directory, int showCmd);
[CCode (cname = "CoInitialize", cheader_filename = "windows.h")] [CCode (cname = "CoInitialize", cheader_filename = "windows.h")]
private static extern int CoInitialize(void* reserved); private static extern int CoInitialize(void* reserved);
@ -14,7 +14,7 @@ public class Util {
[CCode (cname = "CoUninitialize", cheader_filename = "windows.h")] [CCode (cname = "CoUninitialize", cheader_filename = "windows.h")]
private static extern void CoUninitialize(); private static extern void CoUninitialize();
private static int* ShellExecute(string operation, string file) { private static int ShellExecute(string operation, string file) {
CoInitialize(null); CoInitialize(null);
var result = ShellExecuteA(null, operation, file, null, null, 1); var result = ShellExecuteA(null, operation, file, null, null, 1);
CoUninitialize(); CoUninitialize();

View file

@ -2,7 +2,6 @@ namespace Dino {
private extern const string SYSTEM_LIBDIR_NAME; private extern const string SYSTEM_LIBDIR_NAME;
private extern const string SYSTEM_PLUGIN_DIR; private extern const string SYSTEM_PLUGIN_DIR;
private extern const string SYSTEM_LOCALEDIR_NAME;
public class SearchPathGenerator { public class SearchPathGenerator {
@ -13,21 +12,14 @@ public class SearchPathGenerator {
} }
public string get_locale_path(string gettext_package, string locale_install_dir) { public string get_locale_path(string gettext_package, string locale_install_dir) {
if (exec_path != null) { string? locale_dir = null;
var exec_dir = Path.get_dirname(exec_path); if (Path.get_dirname(exec_path).contains("dino") || Path.get_dirname(exec_path) == "." || Path.get_dirname(exec_path).contains("build")) {
string[] search_paths = new string[] { string exec_locale = Path.build_filename(Path.get_dirname(exec_path), "locale");
Path.build_filename(exec_dir, "locale"), if (FileUtils.test(Path.build_filename(exec_locale, "en", "LC_MESSAGES", gettext_package + ".mo"), FileTest.IS_REGULAR)) {
Path.build_filename(Path.get_dirname(exec_dir), SYSTEM_LOCALEDIR_NAME) locale_dir = exec_locale;
};
foreach (var path in search_paths) {
if (FileUtils.test(Path.build_filename(path, "en", "LC_MESSAGES", gettext_package + ".mo"), FileTest.IS_REGULAR)) {
debug(@"Found locale $(gettext_package).mo in $(path)");
return path;
} }
} }
} return locale_dir ?? locale_install_dir;
return locale_install_dir;
} }
public string[] get_plugin_paths() { public string[] get_plugin_paths() {

View file

@ -26,5 +26,14 @@
</layout> </layout>
</object> </object>
</child> </child>
<child>
<object class="GtkImage" id="status_image">
<property name="pixel-size">12</property>
<layout>
<property name="column">2</property>
<property name="row">0</property>
</layout>
</object>
</child>
</object> </object>
</interface> </interface>

View file

@ -141,17 +141,20 @@
</object> </object>
</child> </child>
<child> <child>
<object class="AdwPreferencesGroup"> <object class="AdwPreferencesGroup" id="select_lang_group">
<property name="visible">False</property>
<child> <child>
<object class="AdwActionRow"> <object class="AdwComboRow" id="select_lang_comborow">
<property name="title" translatable="yes">_Dark theme</property> <property name="title" translatable="yes">Select language</property>
<property name="use-underline">True</property> <property name="subtitle" translatable="yes">Application restart required</property>
<property name="activatable-widget">dark_theme</property> <property name="model">
<child type="suffix"> <object class="GtkStringList" id="select_lang_list">
<object class="GtkSwitch" id="dark_theme"> <items>
<property name="valign">center</property> <item>English</item>
<item>Русский</item>
</items>
</object> </object>
</child> </property>
</object> </object>
</child> </child>
</object> </object>

View file

@ -533,10 +533,12 @@ msgid "Local Settings"
msgstr "" msgstr ""
#: main/src/ui/contact_details/settings_provider.vala:28 #: main/src/ui/contact_details/settings_provider.vala:28
#: main/data/settings_dialog.ui:23
msgid "Send typing notifications" msgid "Send typing notifications"
msgstr "" msgstr ""
#: main/src/ui/contact_details/settings_provider.vala:33 #: main/src/ui/contact_details/settings_provider.vala:33
#: main/data/settings_dialog.ui:32
msgid "Send read receipts" msgid "Send read receipts"
msgstr "" msgstr ""
@ -1010,48 +1012,24 @@ msgstr ""
msgid "Add Contact" msgid "Add Contact"
msgstr "" msgstr ""
#: main/data/settings_dialog.ui:14 #: main/data/settings_dialog.ui:41
msgid "Default encryption for 1-on-1 chats"
msgstr ""
#: main/data/settings_dialog.ui:19
msgid "Ask"
msgstr ""
#: main/data/settings_dialog.ui:57
msgid "Send _Typing Notifications"
msgstr ""
#: main/data/settings_dialog.ui:85
msgid "_Notifications"
msgstr ""
#: main/data/settings_dialog.ui:69
msgid "Send _Read Receipts"
msgstr ""
#: main/data/settings_dialog.ui:86
msgid "Notify when a new message arrives" msgid "Notify when a new message arrives"
msgstr "" msgstr ""
#: main/data/settings_dialog.ui:102 #: main/data/settings_dialog.ui:50
msgid "_Convert Smileys to Emoji" msgid "Convert smileys to emojis"
msgstr "" msgstr ""
#: main/data/settings_dialog.ui:118 #: main/data/settings_dialog.ui:59
msgid "_Display send button" msgid "Check spelling"
msgstr "" msgstr ""
#: main/data/settings_dialog.ui:130 #: main/data/settings_dialog.ui:148
msgid "_Use Enter key to start a new line" msgid "Select language"
msgstr "" msgstr ""
#: main/data/settings_dialog.ui:131 #: main/data/settings_dialog.ui:149
msgid "If disabled, use Shift+Enter to start a new line" msgid "Application restart required"
msgstr ""
#: main/data/settings_dialog.ui:147
msgid "_Dark theme"
msgstr "" msgstr ""
#: main/data/im.dino.Dino.appdata.xml.in:7 #: main/data/im.dino.Dino.appdata.xml.in:7

View file

@ -563,7 +563,7 @@ msgstr "Уведомления"
#: main/src/ui/contact_details/settings_provider.vala:55 #: main/src/ui/contact_details/settings_provider.vala:55
msgid "Pin conversation" msgid "Pin conversation"
msgstr "Закрепить беседу" msgstr ""
#: main/src/ui/contact_details/settings_provider.vala:55 #: main/src/ui/contact_details/settings_provider.vala:55
msgid "Pins the conversation to the top of the conversation list" msgid "Pins the conversation to the top of the conversation list"
@ -826,16 +826,16 @@ msgstr "Прочтите %s, чтобы узнать о процессе авт
#: main/src/ui/conversation_content_view/message_widget.vala:213 #: main/src/ui/conversation_content_view/message_widget.vala:213
msgid "Edit message" msgid "Edit message"
msgstr "Редактировать сообщение" msgstr ""
#: main/src/ui/conversation_content_view/reactions_widget.vala:102 #: main/src/ui/conversation_content_view/reactions_widget.vala:102
msgid "You" msgid "You"
msgstr "Вы" msgstr ""
#: main/src/ui/conversation_content_view/reactions_widget.vala:128 #: main/src/ui/conversation_content_view/reactions_widget.vala:128
#: main/src/ui/conversation_content_view/item_actions.vala:8 #: main/src/ui/conversation_content_view/item_actions.vala:8
msgid "Add reaction" msgid "Add reaction"
msgstr "Добавить реакцию" msgstr ""
#: main/src/ui/conversation_content_view/file_image_widget.vala:53 #: main/src/ui/conversation_content_view/file_image_widget.vala:53
#: main/src/ui/conversation_content_view/file_default_widget.vala:57 #: main/src/ui/conversation_content_view/file_default_widget.vala:57
@ -947,7 +947,7 @@ msgstr "несколько секунд"
#: main/src/ui/conversation_content_view/conversation_item_skeleton.vala:191 #: main/src/ui/conversation_content_view/conversation_item_skeleton.vala:191
msgid "Delivered" msgid "Delivered"
msgstr "Доставленo" msgstr ""
#: main/src/ui/conversation_content_view/conversation_item_skeleton.vala:195 #: main/src/ui/conversation_content_view/conversation_item_skeleton.vala:195
msgid "Read" msgid "Read"
@ -959,15 +959,15 @@ msgstr "Этот контакт хочет добавить вас в свой
#: main/src/ui/conversation_content_view/item_actions.vala:21 #: main/src/ui/conversation_content_view/item_actions.vala:21
msgid "This conversation does not support reactions." msgid "This conversation does not support reactions."
msgstr "Этот разговор не поддерживает реакции." msgstr ""
#: main/src/ui/conversation_content_view/item_actions.vala:33 #: main/src/ui/conversation_content_view/item_actions.vala:33
msgid "Reply" msgid "Reply"
msgstr "Ответить" msgstr ""
#: main/src/ui/conversation_content_view/item_actions.vala:43 #: main/src/ui/conversation_content_view/item_actions.vala:43
msgid "This conversation does not support replies." msgid "This conversation does not support replies."
msgstr "Этот разговор не поддерживает ответы" msgstr ""
#: main/src/ui/conversation_content_view/file_default_widget.vala:64 #: main/src/ui/conversation_content_view/file_default_widget.vala:64
#, c-format #, c-format
@ -1006,7 +1006,7 @@ msgstr "Тут пустовато"
#: main/data/unified_main_content.ui:47 #: main/data/unified_main_content.ui:47
msgid "Click + to start a chat or join a channel" msgid "Click + to start a chat or join a channel"
msgstr "Нажмите +, чтобы начать чат или присоединиться к каналу" msgstr ""
#: main/data/add_conversation/conference_details_fragment.ui:20 #: main/data/add_conversation/conference_details_fragment.ui:20
#: main/data/add_conversation/add_groupchat_dialog.ui:40 #: main/data/add_conversation/add_groupchat_dialog.ui:40
@ -1028,49 +1028,25 @@ msgstr "Псевдоним"
msgid "Add Contact" msgid "Add Contact"
msgstr "Добавить контакт" msgstr "Добавить контакт"
#: main/data/settings_dialog.ui:14 #: main/data/settings_dialog.ui:41
msgid "Default encryption for 1-on-1 chats"
msgstr "Шифрование по умолчанию для 1-на-1 чатов"
#: main/data/settings_dialog.ui:19
msgid "Ask"
msgstr "Спрашивать"
#: main/data/settings_dialog.ui:57
msgid "Send _Typing Notifications"
msgstr "Отправлять уведомления при наборе сообщения"
#: main/data/settings_dialog.ui:85
msgid "_Notifications"
msgstr "Уведомления"
#: main/data/settings_dialog.ui:69
msgid "Send _Read Receipts"
msgstr "Отправлять уведомления о прочтении"
#: main/data/settings_dialog.ui:86
msgid "Notify when a new message arrives" msgid "Notify when a new message arrives"
msgstr "Уведомлять о новых сообщениях" msgstr "Уведомлять о новых сообщениях"
#: main/data/settings_dialog.ui:102 #: main/data/settings_dialog.ui:50
msgid "_Convert Smileys to Emoji" msgid "Convert smileys to emojis"
msgstr "Превращать смайлы в эмодзи" msgstr "Превращать смайлы в эмодзи"
#: main/data/settings_dialog.ui:118 #: main/data/settings_dialog.ui:59
msgid "_Display send button" msgid "Check spelling"
msgstr "Показывать кнопку отправки" msgstr "Проверка орфографии"
#: main/data/settings_dialog.ui:130 #: main/data/settings_dialog.ui:148
msgid "_Use Enter key to start a new line" msgid "Select language"
msgstr "Использовать Enter для вставки новой строки" msgstr "Выбор языка"
#: main/data/settings_dialog.ui:131 #: main/data/settings_dialog.ui:149
msgid "If disabled, use Shift+Enter to start a new line" msgid "Application restart required"
msgstr "Если опция недоступна, используйте Shift+Enter для вставки новой строки" msgstr "Требуется перезапуск приложения"
#: main/data/settings_dialog.ui:147
msgid "_Dark theme"
msgstr "Тёмная тема"
#: main/data/im.dino.Dino.appdata.xml.in:7 #: main/data/im.dino.Dino.appdata.xml.in:7
msgid "Modern XMPP Chat Client" msgid "Modern XMPP Chat Client"

View file

@ -34,13 +34,7 @@ protected class RosterList {
foreach (ulong handler_id in handler_ids) stream_interactor.get_module(RosterManager.IDENTITY).disconnect(handler_id); foreach (ulong handler_id in handler_ids) stream_interactor.get_module(RosterManager.IDENTITY).disconnect(handler_id);
}); });
foreach (Account a in accounts) { foreach (Account a in accounts) fetch_roster_items(a);
ListRow own_account_row = new ListRow.from_jid(stream_interactor, a.bare_jid, a, accounts.size > 1);
ListBoxRow own_account_lbrow = new ListBoxRow() { child = own_account_row };
list_box.append(own_account_lbrow);
fetch_roster_items(a);
}
} }
private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) { private void on_removed_roster_item(Account account, Jid jid, Roster.Item roster_item) {
@ -53,7 +47,7 @@ protected class RosterList {
private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) { private void on_updated_roster_item(Account account, Jid jid, Roster.Item roster_item) {
on_removed_roster_item(account, jid, roster_item); on_removed_roster_item(account, jid, roster_item);
ListRow row = new ListRow.from_jid(stream_interactor, roster_item.jid, account, accounts.size > 1); ListRow row = new ListRow.from_jid(stream_interactor, roster_item.jid, account, accounts.size > 1);
ListBoxRow list_box_row = new ListBoxRow() { child = row }; ListBoxRow list_box_row = new ListBoxRow() { child=row };
rows[account][jid] = list_box_row; rows[account][jid] = list_box_row;
list_box.append(list_box_row); list_box.append(list_box_row);
list_box.invalidate_sort(); list_box.invalidate_sort();

View file

@ -29,10 +29,7 @@ public class Dino.Ui.Application : Adw.Application, Dino.Application {
public Application() throws Error { public Application() throws Error {
Object(application_id: "im.dino.Dino", flags: ApplicationFlags.HANDLES_OPEN); Object(application_id: "im.dino.Dino", flags: ApplicationFlags.HANDLES_OPEN);
init();
var style_manager = Adw.StyleManager.get_default();
bool system_dark_theme = style_manager.system_supports_color_schemes && style_manager.dark;
init(system_dark_theme);
Environment.set_application_name("Dino"); Environment.set_application_name("Dino");
Window.set_default_icon_name("im.dino.Dino"); Window.set_default_icon_name("im.dino.Dino");
@ -71,19 +68,6 @@ public class Dino.Ui.Application : Adw.Application, Dino.Application {
} }
} }
}); });
settings.dark_theme_update.connect((is_dark) => {
var manager = Adw.StyleManager.get_default();
if (is_dark != manager.dark) {
if (is_dark) {
manager.set_color_scheme(Adw.ColorScheme.FORCE_DARK);
} else {
manager.set_color_scheme(Adw.ColorScheme.FORCE_LIGHT);
}
}
});
settings.dark_theme_update(settings.dark_theme); // Change theme at startup.
}); });
activate.connect(() => { activate.connect(() => {

View file

@ -73,9 +73,6 @@ public class FileImageWidget : Box {
image_overlay_toolbar.visible = false; image_overlay_toolbar.visible = false;
}); });
// Set tooltip to display the file name on hover
image.set_tooltip_text(file_name);
this.append(overlay); this.append(overlay);
} }
} }

View file

@ -90,8 +90,7 @@ public class FileWidget : SizeRequestBox {
private async void update_widget() { private async void update_widget() {
if (show_image() && state != State.IMAGE if (show_image() && state != State.IMAGE
&& file_transfer.state == FileTransfer.State.COMPLETE && file_transfer.state == FileTransfer.State.COMPLETE) {
&& file_transfer.get_file().query_exists()) {
var content_bak = content; var content_bak = content;
FileImageWidget file_image_widget = null; FileImageWidget file_image_widget = null;
@ -110,8 +109,7 @@ public class FileWidget : SizeRequestBox {
} catch (Error e) { } } catch (Error e) { }
} }
if (state != State.DEFAULT || if (state != State.DEFAULT) {
(file_transfer.state == FileTransfer.State.COMPLETE && !file_transfer.get_file().query_exists())) {
if (content != null) this.remove(content); if (content != null) this.remove(content);
FileDefaultWidget default_file_widget = new FileDefaultWidget(); FileDefaultWidget default_file_widget = new FileDefaultWidget();
default_widget_controller = new FileDefaultWidgetController(default_file_widget); default_widget_controller = new FileDefaultWidgetController(default_file_widget);
@ -178,17 +176,11 @@ public class FileWidgetController : Object {
} }
private void open_file() { private void open_file() {
if (file_transfer.get_file().query_exists()) { try{
try {
Dino.Util.launch_default_for_uri(file_transfer.get_file().get_uri()); Dino.Util.launch_default_for_uri(file_transfer.get_file().get_uri());
} catch (Error err) { } catch (Error err) {
warning("Failed to open %s - %s", file_transfer.get_file().get_uri(), err.message); warning("Failed to open %s - %s", file_transfer.get_file().get_uri(), err.message);
} }
} else {
warning("File %s does not exist", file_transfer.get_file().get_uri());
file_transfer.state = FileTransfer.State.NOT_STARTED;
widget.activate_action("file.download", null);
}
} }
private void save_file() { private void save_file() {
@ -252,12 +244,8 @@ public class FileDefaultWidgetController : Object {
private void update_file_info() { private void update_file_info() {
state = file_transfer.state; state = file_transfer.state;
if (state == FileTransfer.State.COMPLETE && !file_transfer.get_file().query_exists()) {
state = FileTransfer.State.NOT_STARTED;
file_transfer.state = FileTransfer.State.NOT_STARTED;
}
widget.update_file_info(file_transfer.mime_type, file_transfer.transferred_bytes, widget.update_file_info(file_transfer.mime_type, file_transfer.transferred_bytes,
file_transfer.direction, state, file_transfer.size); file_transfer.direction, file_transfer.state, file_transfer.size);
} }
private void on_clicked() { private void on_clicked() {
@ -266,11 +254,10 @@ public class FileDefaultWidgetController : Object {
widget.activate_action("file.open", null); widget.activate_action("file.open", null);
break; break;
case FileTransfer.State.NOT_STARTED: case FileTransfer.State.NOT_STARTED:
case FileTransfer.State.FAILED:
widget.activate_action("file.download", null); widget.activate_action("file.download", null);
break; break;
default: default:
// Clicking doesn't do anything in IN_PROGRESS state // Clicking doesn't do anything in FAILED and IN_PROGRESS states
break; break;
} }
} }

View file

@ -44,11 +44,7 @@ public class Dialog : Gtk.Dialog {
}); });
image_button.clicked.connect(show_select_avatar); image_button.clicked.connect(show_select_avatar);
alias_hybrid.entry.changed.connect(() => { selected_account.alias = alias_hybrid.text; }); alias_hybrid.entry.changed.connect(() => { selected_account.alias = alias_hybrid.text; });
password_hybrid.entry.changed.connect(() => { password_hybrid.entry.changed.connect(() => { selected_account.password = password_hybrid.text; });
if (password_hybrid.text != "************") {
selected_account.password = password_hybrid.text;
}
});
password_change_btn.clicked.connect(show_change_psswd_dialog); password_change_btn.clicked.connect(show_change_psswd_dialog);
Util.LabelHybridGroup label_hybrid_group = new Util.LabelHybridGroup(); Util.LabelHybridGroup label_hybrid_group = new Util.LabelHybridGroup();
@ -72,7 +68,6 @@ public class Dialog : Gtk.Dialog {
settings_list.attach(widget, 1, row_index, 2); settings_list.attach(widget, 1, row_index, 2);
row_index++; row_index++;
password_hybrid.text = "************";
} }
} }
@ -197,7 +192,6 @@ public class Dialog : Gtk.Dialog {
} }
private void populate_grid_data(Account account) { private void populate_grid_data(Account account) {
active_switch.sensitive = false;
active_switch.state_set.disconnect(change_account_state); active_switch.state_set.disconnect(change_account_state);
picture.model = new ViewModel.CompatAvatarPictureModel(stream_interactor).add_participant(new Conversation(account.bare_jid, account, Conversation.Type.CHAT), account.bare_jid); picture.model = new ViewModel.CompatAvatarPictureModel(stream_interactor).add_participant(new Conversation(account.bare_jid, account, Conversation.Type.CHAT), account.bare_jid);
@ -206,7 +200,7 @@ public class Dialog : Gtk.Dialog {
alias_hybrid.text = account.alias ?? ""; alias_hybrid.text = account.alias ?? "";
password_hybrid.entry.input_purpose = InputPurpose.PASSWORD; password_hybrid.entry.input_purpose = InputPurpose.PASSWORD;
password_hybrid.text = account.password;
update_status_label(account); update_status_label(account);
@ -228,14 +222,11 @@ public class Dialog : Gtk.Dialog {
ConnectionManager.ConnectionState state = stream_interactor.connection_manager.get_state(account); ConnectionManager.ConnectionState state = stream_interactor.connection_manager.get_state(account);
switch (state) { switch (state) {
case ConnectionManager.ConnectionState.CONNECTING: case ConnectionManager.ConnectionState.CONNECTING:
active_switch.sensitive = false;
state_label.label = _("Connecting…"); break; state_label.label = _("Connecting…"); break;
case ConnectionManager.ConnectionState.CONNECTED: case ConnectionManager.ConnectionState.CONNECTED:
active_switch.sensitive = true;
password_change_btn.sensitive = true; password_change_btn.sensitive = true;
state_label.label = _("Connected"); break; state_label.label = _("Connected"); break;
case ConnectionManager.ConnectionState.DISCONNECTED: case ConnectionManager.ConnectionState.DISCONNECTED:
active_switch.sensitive = true;
password_change_btn.sensitive = false; password_change_btn.sensitive = false;
state_label.label = _("Disconnected"); break; state_label.label = _("Disconnected"); break;
} }

View file

@ -29,8 +29,8 @@ public class List : Box {
list_box.set_filter_func(filter); list_box.set_filter_func(filter);
search_entry.search_changed.connect(refilter); search_entry.search_changed.connect(refilter);
stream_interactor.get_module(PresenceManager.IDENTITY).show_received.connect(on_show_received); stream_interactor.get_module(PresenceManager.IDENTITY).show_received.connect(on_received_online_presence);
stream_interactor.get_module(PresenceManager.IDENTITY).received_offline_presence.connect(on_quit_received); stream_interactor.get_module(PresenceManager.IDENTITY).received_offline_presence.connect(on_received_offline_presence);
initialize_for_conversation(conversation); initialize_for_conversation(conversation);
} }
@ -63,11 +63,12 @@ public class List : Box {
this.conversation = conversation; this.conversation = conversation;
var identity = stream_interactor.get_module(MucManager.IDENTITY); var identity = stream_interactor.get_module(MucManager.IDENTITY);
Gee.List<Jid>? members = identity.get_members(conversation.counterpart, conversation.account); Gee.List<Jid>? members = identity.get_all_members(conversation.counterpart, conversation.account);
if (members != null) { if (members != null) {
// Add all members and their status to the list // Add all members and their status to the list
foreach (Jid member in members) { foreach (Jid member in members) {
add_member(member); //use add_member_with_status if you want to get online/offline statuses bool online = get_status(member, conversation.account);
add_member(member, online);
} }
} }
list_box.invalidate_filter(); list_box.invalidate_filter();
@ -82,7 +83,7 @@ public class List : Box {
list_box.invalidate_filter(); list_box.invalidate_filter();
} }
public void add_member_with_status(Jid jid, bool online) { public void add_member(Jid jid, bool online) {
// HACK: // HACK:
// Here we track members based on their names (not jids) // Here we track members based on their names (not jids)
// Sometimes the same member can be referenced with different jids, for example: // Sometimes the same member can be referenced with different jids, for example:
@ -123,35 +124,6 @@ public class List : Box {
} }
} }
public void add_member(Jid jid) {
var row_wrapper = new ListRow(stream_interactor, conversation, jid);
var widget = row_wrapper.get_widget();
string member_name = null;
if (jid.resourcepart != null) {
member_name = jid.resourcepart;
} else {
member_name = jid.localpart;
}
if (member_name == null) {
return;
}
row_wrappers[widget] = row_wrapper;
rows[member_name] = widget;
list_box.append(widget);
}
public void remove_member(Jid jid) {
var member_name = jid.resourcepart;
if (member_name == null) {
return;
}
list_box.remove(rows[member_name]);
rows.unset(member_name);
}
private void on_received_offline_presence(Jid jid, Account account) { private void on_received_offline_presence(Jid jid, Account account) {
if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) { if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) {
var member_name = jid.resourcepart; var member_name = jid.resourcepart;
@ -167,19 +139,6 @@ public class List : Box {
} }
} }
private void on_quit_received(Jid jid, Account account) {
if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) {
var member_name = jid.resourcepart;
if (member_name == null) {
return;
}
if (rows.has_key(member_name)) {
remove_member(jid);
}
list_box.invalidate_filter();
}
}
private void on_received_online_presence(Jid jid, Account account) { private void on_received_online_presence(Jid jid, Account account) {
if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) { if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) {
var member_name = jid.resourcepart; var member_name = jid.resourcepart;
@ -188,7 +147,7 @@ public class List : Box {
} }
if (!rows.has_key(member_name)) { if (!rows.has_key(member_name)) {
add_member_with_status(jid, true); add_member(jid, true);
} }
row_wrappers[rows[member_name]].set_online(); row_wrappers[rows[member_name]].set_online();
@ -197,20 +156,6 @@ public class List : Box {
} }
} }
private void on_show_received(Jid jid, Account account) {
if (conversation != null && conversation.counterpart.equals_bare(jid) && jid.is_full()) {
var member_name = jid.resourcepart;
if (member_name == null) {
return;
}
if (!rows.has_key(member_name)) {
add_member(jid);
}
list_box.invalidate_filter();
}
}
private void header(ListBoxRow row, ListBoxRow? before_row) { private void header(ListBoxRow row, ListBoxRow? before_row) {
ListRow row_wrapper1 = row_wrappers[row.get_child()]; ListRow row_wrapper1 = row_wrappers[row.get_child()];
Xmpp.Xep.Muc.Affiliation? a1 = stream_interactor.get_module(MucManager.IDENTITY).get_affiliation(conversation.counterpart, row_wrapper1.jid, row_wrapper1.conversation.account); Xmpp.Xep.Muc.Affiliation? a1 = stream_interactor.get_module(MucManager.IDENTITY).get_affiliation(conversation.counterpart, row_wrapper1.jid, row_wrapper1.conversation.account);

View file

@ -10,6 +10,7 @@ public class ListRow : Object {
private Grid main_grid; private Grid main_grid;
private AvatarPicture picture; private AvatarPicture picture;
public Label name_label; public Label name_label;
public Image status_image;
public Conversation? conversation; public Conversation? conversation;
public Jid? jid; public Jid? jid;
@ -18,6 +19,7 @@ public class ListRow : Object {
main_grid = (Grid) builder.get_object("main_grid"); main_grid = (Grid) builder.get_object("main_grid");
picture = (AvatarPicture) builder.get_object("picture"); picture = (AvatarPicture) builder.get_object("picture");
name_label = (Label) builder.get_object("name_label"); name_label = (Label) builder.get_object("name_label");
status_image = (Image) builder.get_object("status_image");
main_grid.set_column_spacing(10); main_grid.set_column_spacing(10);
main_grid.set_column_homogeneous(false); main_grid.set_column_homogeneous(false);
main_grid.set_baseline_row(1); main_grid.set_baseline_row(1);
@ -41,9 +43,11 @@ public class ListRow : Object {
} }
public void set_online() { public void set_online() {
status_image.icon_name = "dino-status-online-bright";
} }
public void set_offline() { public void set_offline() {
status_image.icon_name = "dino-status-offline";
} }
} }

View file

@ -15,7 +15,10 @@ class SettingsDialog : Adw.PreferencesWindow {
[GtkChild] private unowned CheckButton encryption_radio_openpgp; [GtkChild] private unowned CheckButton encryption_radio_openpgp;
[GtkChild] private unowned Switch send_button_switch; [GtkChild] private unowned Switch send_button_switch;
[GtkChild] private unowned Switch enter_newline_switch; [GtkChild] private unowned Switch enter_newline_switch;
[GtkChild] private unowned Switch dark_theme; #if ENABLE_SELECT_LANG
[GtkChild] private unowned Adw.ComboRow select_lang_comborow;
[GtkChild] private unowned Adw.PreferencesGroup select_lang_group;
#endif
Dino.Entities.Settings settings = Dino.Application.get_default().settings; Dino.Entities.Settings settings = Dino.Application.get_default().settings;
@ -33,7 +36,6 @@ class SettingsDialog : Adw.PreferencesWindow {
send_button_switch.active = settings.send_button; send_button_switch.active = settings.send_button;
enter_newline_switch.active = settings.enter_newline; enter_newline_switch.active = settings.enter_newline;
enter_newline_switch.sensitive = settings.send_button; enter_newline_switch.sensitive = settings.send_button;
dark_theme.active = settings.dark_theme;
typing_switch.notify["active"].connect(() => { settings.send_typing = typing_switch.active; } ); typing_switch.notify["active"].connect(() => { settings.send_typing = typing_switch.active; } );
marker_switch.notify["active"].connect(() => { settings.send_marker = marker_switch.active; } ); marker_switch.notify["active"].connect(() => { settings.send_marker = marker_switch.active; } );
@ -67,7 +69,21 @@ class SettingsDialog : Adw.PreferencesWindow {
enter_newline_switch.active = visible; enter_newline_switch.active = visible;
} }
}); });
dark_theme.notify["active"].connect(() => { settings.dark_theme = dark_theme.active; });
#if ENABLE_SELECT_LANG
var lang_short_list = new Gee.ArrayList<string>();
lang_short_list.add("en");
lang_short_list.add("ru");
select_lang_comborow.set_selected(lang_short_list.index_of(settings.ui_language));
select_lang_comborow.notify["selected-item"].connect(() => {
settings.ui_language = lang_short_list.get((int)select_lang_comborow.get_selected());
});
select_lang_group.visible = true;
#endif
} }
} }

View file

@ -24,6 +24,10 @@ else
endforeach endforeach
endif endif
if get_option('select-lang').allowed()
add_project_arguments('-D', 'ENABLE_SELECT_LANG', language: 'vala')
endif
if get_option('crypto-backend') == 'auto' if get_option('crypto-backend') == 'auto'
# Prefer libgcrypt/gnutls over openssl because glib-networking is usually # Prefer libgcrypt/gnutls over openssl because glib-networking is usually
# built with gnutls anyway. # built with gnutls anyway.

View file

@ -17,3 +17,5 @@ option('plugin-rtp-webrtc-audio-processing', type: 'feature', description: 'Voic
option('use-soup2', type: 'boolean', value: false, description: 'Use libsoup version 2 instead of 3') option('use-soup2', type: 'boolean', value: false, description: 'Use libsoup version 2 instead of 3')
option('with-wasapi', type: 'boolean', value: true, description: 'Use wasapi insted of directsound on windows') option('with-wasapi', type: 'boolean', value: true, description: 'Use wasapi insted of directsound on windows')
option('select-lang', type: 'feature', value: 'disabled', description: 'Enable language change in settings')

View file

@ -6,21 +6,6 @@ using Xmpp.Xep;
private extern const size_t NICE_ADDRESS_STRING_LEN; private extern const size_t NICE_ADDRESS_STRING_LEN;
public class Dino.Plugins.Ice.Plugin : RootInterface, Object { public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
private const int64 delay_min = 300; // 10mn
private const int64 delay_max = (int64) uint.MAX;
private class TimerPayload {
public Account account { get; set; }
public uint timeout_handle_id;
public TimerPayload(Account account, uint timeout_handle_id) {
this.account = account;
this.timeout_handle_id = timeout_handle_id;
}
}
private HashMap<XmppStream, TimerPayload> timeouts = new HashMap<XmppStream, TimerPayload>(XmppStream.hash_func, XmppStream.equals_func);
public Dino.Application app; public Dino.Application app;
public void registered(Dino.Application app) { public void registered(Dino.Application app) {
@ -37,10 +22,10 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
stream.get_module(JingleRawUdp.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses); stream.get_module(JingleRawUdp.Module.IDENTITY).set_local_ip_address_handler(get_local_ip_addresses);
} }
}); });
app.stream_interactor.connection_manager.connection_state_changed.connect(on_connection_state_changed); app.stream_interactor.stream_negotiated.connect(on_stream_negotiated);
} }
private async void external_discovery_refresh_services(Account account, XmppStream stream) { private async void on_stream_negotiated(Account account, XmppStream stream) {
Module? ice_udp_module = stream.get_module(JingleIceUdp.Module.IDENTITY) as Module; Module? ice_udp_module = stream.get_module(JingleIceUdp.Module.IDENTITY) as Module;
if (ice_udp_module == null) return; if (ice_udp_module == null) return;
Gee.List<Xep.ExternalServiceDiscovery.Service> services = yield ExternalServiceDiscovery.request_services(stream); Gee.List<Xep.ExternalServiceDiscovery.Service> services = yield ExternalServiceDiscovery.request_services(stream);
@ -60,28 +45,6 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
} }
} }
} }
if (ice_udp_module.turn_service != null) {
DateTime? expires = ice_udp_module.turn_service.expires;
if (expires != null) {
int64 delay = (expires.to_unix() - new DateTime.now_utc().to_unix()) / 2;
if (delay >= delay_min && delay <= delay_max) {
debug("Next server external service discovery in %lds (because of TURN credentials' expiry time)", (long) delay);
uint timeout_handle_id = Timeout.add_seconds((uint) delay, () => {
on_timeout(stream);
return false;
});
timeouts[stream] = new TimerPayload(account, timeout_handle_id);
timeouts[stream].account = account;
timeouts[stream].timeout_handle_id = timeout_handle_id;
} else {
warning("Bogus TURN credentials' expiry time (delay value = %ld), *not* planning next service discovery", (long) delay);
}
}
}
if (ice_udp_module.stun_ip == null) { if (ice_udp_module.stun_ip == null) {
InetAddress ip = yield lookup_ipv4_addess("stun.dino.im"); InetAddress ip = yield lookup_ipv4_addess("stun.dino.im");
if (ip == null) return; if (ip == null) return;
@ -93,31 +56,6 @@ public class Dino.Plugins.Ice.Plugin : RootInterface, Object {
} }
} }
public void on_timeout(XmppStream stream) {
if (!timeouts.has_key(stream)) return;
TimerPayload pl = timeouts[stream];
timeouts.unset(stream);
external_discovery_refresh_services.begin(pl.account, stream);
}
public void on_connection_state_changed(Account account, ConnectionManager.ConnectionState state) {
switch(state)
{
case ConnectionManager.ConnectionState.DISCONNECTED:
XmppStream? stream = app.stream_interactor.connection_manager.get_stream(account);
if (stream == null) return;
if (!timeouts.has_key(stream)) return;
Source.remove(timeouts[stream].timeout_handle_id);
timeouts.unset(stream);
break;
case ConnectionManager.ConnectionState.CONNECTED:
XmppStream? stream = app.stream_interactor.connection_manager.get_stream(account);
external_discovery_refresh_services(account, stream);
break;
}
}
public void shutdown() { public void shutdown() {
// Nothing to do // Nothing to do
} }

View file

@ -1,10 +1,9 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: dino-openpgp-0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-09 22:16+0200\n" "POT-Creation-Date: 2023-02-07 21:31+0100\n"
"PO-Revision-Date: 2024-06-09 22:39+0200\n" "PO-Revision-Date: 2020-04-16 20:11+0000\n"
"Last-Translator: eerielili \n"
"Language-Team: German <https://hosted.weblate.org/projects/dino/plugin-" "Language-Team: German <https://hosted.weblate.org/projects/dino/plugin-"
"openpgp/de/>\n" "openpgp/de/>\n"
"Language: de\n" "Language: de\n"
@ -12,11 +11,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Poedit 3.4.2\n" "X-Generator: Weblate 4.0.1-dev\n"
#: plugins/openpgp/src/account_settings_entry.vala:68 #: plugins/openpgp/src/account_settings_entry.vala:68
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
#: plugins/openpgp/src/account_settings_entry.vala:113 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "Key publishing disabled" msgid "Key publishing disabled"
msgstr "Schlüsselveröffentlichung deaktiviert" msgstr "Schlüsselveröffentlichung deaktiviert"
@ -25,40 +24,18 @@ msgid "Error in GnuPG"
msgstr "Fehler in GnuPG" msgstr "Fehler in GnuPG"
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
msgid "" msgid "No keys available. Generate one!"
"No keys available. Generate one or check if your keys aren't expired or " msgstr "Keine Schlüssel vorhanden. Erzeuge einen!"
"revoked!"
msgstr ""
"Keine Schlüssel vorhanden. Erstellen Sie einen oder prüfen Sie,"
"ob Ihre Schlüssel nicht abgelaufen sind oder widerrufen!"
#: plugins/openpgp/src/account_settings_entry.vala:101
#: plugins/openpgp/src/account_settings_entry.vala:95
msgid "expired!"
msgstr "abgelaufen"
#: plugins/openpgp/src/account_settings_entry.vala:95
msgid "revoked!"
msgstr "widerrufen!"
#: plugins/openpgp/src/account_settings_entry.vala:96
msgid "Attention required!"
msgstr "Achtung!"
#: plugins/openpgp/src/account_settings_entry.vala:96
#, c-format
msgid "Your key %s is %s"
msgstr "Ihr Schlüssel %s is %s"
#: plugins/openpgp/src/account_settings_entry.vala:113
msgid "Select key" msgid "Select key"
msgstr "Wähle einen Schlüssel" msgstr "Wähle einen Schlüssel"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Loading…" msgid "Loading…"
msgstr "Lade…" msgstr "Lade…"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Querying GnuPG" msgid "Querying GnuPG"
msgstr "Frage GnuPG ab" msgstr "Frage GnuPG ab"
@ -69,3 +46,6 @@ msgstr "Schlüssel nicht im Schlüsselbund"
#: plugins/openpgp/src/contact_details_provider.vala:30 #: plugins/openpgp/src/contact_details_provider.vala:30
msgid "Encryption" msgid "Encryption"
msgstr "Verschlüsselung" msgstr "Verschlüsselung"
#~ msgid "OpenPGP"
#~ msgstr "OpenPGP"

View file

@ -1,68 +1,52 @@
# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION+\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-06-09 22:16+0200\n" "Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2024-06-09 22:18+0200\n" "POT-Creation-Date: 2023-02-07 21:31+0100\n"
"Last-Translator: \n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Language-Team: Dino+\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language: en\n" "Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"X-Generator: Poedit 3.4.2\n"
"X-Poedit-Basepath: ../src\n"
"X-Poedit-KeywordsList: _(\n"
"X-Poedit-SourceCharset: UTF-8\n"
"X-Poedit-SearchPath-0: .\n"
#: account_settings_entry.vala:68 account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:68
#: account_settings_entry.vala:113 #: plugins/openpgp/src/account_settings_entry.vala:72
#: plugins/openpgp/src/account_settings_entry.vala:101
msgid "Key publishing disabled" msgid "Key publishing disabled"
msgstr "" msgstr ""
#: account_settings_entry.vala:68 #: plugins/openpgp/src/account_settings_entry.vala:68
msgid "Error in GnuPG" msgid "Error in GnuPG"
msgstr "" msgstr ""
#: account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
msgid "" msgid "No keys available. Generate one!"
"No keys available. Generate one or check if your keys aren't expired or "
"revoked!"
msgstr "" msgstr ""
#: account_settings_entry.vala:95 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "expired!"
msgstr ""
#: account_settings_entry.vala:95
msgid "revoked!"
msgstr ""
#: account_settings_entry.vala:96
msgid "Attention required!"
msgstr ""
#: account_settings_entry.vala:96
#, c-format
msgid "Your key %s is %s"
msgstr ""
#: account_settings_entry.vala:113
msgid "Select key" msgid "Select key"
msgstr "" msgstr ""
#: account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Loading…" msgid "Loading…"
msgstr "" msgstr ""
#: account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Querying GnuPG" msgid "Querying GnuPG"
msgstr "" msgstr ""
#: contact_details_provider.vala:28 #: plugins/openpgp/src/contact_details_provider.vala:28
msgid "Key not in keychain" msgid "Key not in keychain"
msgstr "" msgstr ""
#: contact_details_provider.vala:30 #: plugins/openpgp/src/contact_details_provider.vala:30
msgid "Encryption" msgid "Encryption"
msgstr "" msgstr ""

View file

@ -7,9 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-09 22:16+0200\n" "POT-Creation-Date: 2023-02-07 21:31+0100\n"
"PO-Revision-Date: 2024-06-09 22:22+0200\n" "PO-Revision-Date: 2020-11-12 17:21+0000\n"
"Last-Translator: \n"
"Language-Team: French <https://hosted.weblate.org/projects/dino/plugin-" "Language-Team: French <https://hosted.weblate.org/projects/dino/plugin-"
"openpgp/fr/>\n" "openpgp/fr/>\n"
"Language: fr\n" "Language: fr\n"
@ -17,11 +16,11 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n" "Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Poedit 3.4.2\n" "X-Generator: Weblate 4.4-dev\n"
#: plugins/openpgp/src/account_settings_entry.vala:68 #: plugins/openpgp/src/account_settings_entry.vala:68
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
#: plugins/openpgp/src/account_settings_entry.vala:113 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "Key publishing disabled" msgid "Key publishing disabled"
msgstr "La publication des clés est désactivée" msgstr "La publication des clés est désactivée"
@ -30,39 +29,18 @@ msgid "Error in GnuPG"
msgstr "Erreur dans GnuPG" msgstr "Erreur dans GnuPG"
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
msgid "" msgid "No keys available. Generate one!"
"No keys available. Generate one or check if your keys aren't expired or " msgstr "Aucune clé nest disponible. Générez-en une!"
"revoked!"
msgstr ""
"Pas de clés disponibles. Générez-en une nouvelle ou vérifier si vos "
"clés ne seraient pas expirées ou révoquées!"
#: plugins/openpgp/src/account_settings_entry.vala:95 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "expired!"
msgstr "expirée!"
#: plugins/openpgp/src/account_settings_entry.vala:95
msgid "revoked!"
msgstr "révoquée!"
#: plugins/openpgp/src/account_settings_entry.vala:96
msgid "Attention required!"
msgstr "Attention requise!"
#: plugins/openpgp/src/account_settings_entry.vala:96
#, c-format
msgid "Your key %s is %s"
msgstr "Votre clé %s est %s"
#: plugins/openpgp/src/account_settings_entry.vala:113
msgid "Select key" msgid "Select key"
msgstr "Choix dune clé" msgstr "Choix dune clé"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Loading…" msgid "Loading…"
msgstr "Chargement…" msgstr "Chargement…"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Querying GnuPG" msgid "Querying GnuPG"
msgstr "Interrogation de GnuPG" msgstr "Interrogation de GnuPG"

View file

@ -7,9 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-06-09 22:16+0200\n" "POT-Creation-Date: 2023-02-07 21:31+0100\n"
"PO-Revision-Date: 2024-06-09 22:39+0200\n" "PO-Revision-Date: 2020-06-02 11:41+0000\n"
"Last-Translator: eerielili\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/dino/plugin-" "Language-Team: Russian <https://hosted.weblate.org/projects/dino/plugin-"
"openpgp/ru/>\n" "openpgp/ru/>\n"
"Language: ru\n" "Language: ru\n"
@ -18,11 +17,11 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Generator: Poedit 3.4.2\n" "X-Generator: Weblate 4.1-dev\n"
#: plugins/openpgp/src/account_settings_entry.vala:68 #: plugins/openpgp/src/account_settings_entry.vala:68
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
#: plugins/openpgp/src/account_settings_entry.vala:113 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "Key publishing disabled" msgid "Key publishing disabled"
msgstr "Публикация ключа отключена" msgstr "Публикация ключа отключена"
@ -31,37 +30,18 @@ msgid "Error in GnuPG"
msgstr "Ошибка в GnuPG" msgstr "Ошибка в GnuPG"
#: plugins/openpgp/src/account_settings_entry.vala:72 #: plugins/openpgp/src/account_settings_entry.vala:72
msgid "" msgid "No keys available. Generate one!"
"No keys available. Generate one or check if your keys aren't expired or "
"revoked!"
msgstr "Нет доступных ключей. Создайте как минимум один, либо проверьте что уже существующие (ранее созданные) ключи не были отозваны или срок их действия не закончился!" msgstr "Нет доступных ключей. Создайте как минимум один, либо проверьте что уже существующие (ранее созданные) ключи не были отозваны или срок их действия не закончился!"
#: plugins/openpgp/src/account_settings_entry.vala:95 #: plugins/openpgp/src/account_settings_entry.vala:101
msgid "expired!"
msgstr "истёк!"
#: plugins/openpgp/src/account_settings_entry.vala:95
msgid "revoked!"
msgstr "отозван!"
#: plugins/openpgp/src/account_settings_entry.vala:96
msgid "Attention required!"
msgstr "внимание!"
#: plugins/openpgp/src/account_settings_entry.vala:96
#, c-format
msgid "Your key %s is %s"
msgstr "Ваш ключ %s %s"
#: plugins/openpgp/src/account_settings_entry.vala:113
msgid "Select key" msgid "Select key"
msgstr "Выбрать ключ" msgstr "Выбрать ключ"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Loading…" msgid "Loading…"
msgstr "Загрузка…" msgstr "Загрузка…"
#: plugins/openpgp/src/account_settings_entry.vala:126 #: plugins/openpgp/src/account_settings_entry.vala:114
msgid "Querying GnuPG" msgid "Querying GnuPG"
msgstr "Запрос GnuPG" msgstr "Запрос GnuPG"

View file

@ -69,7 +69,7 @@ public class AccountSettingsEntry : Plugins.AccountSettingsEntry {
return; return;
} }
if (keys.size == 0) { if (keys.size == 0) {
label.set_markup(build_markup_string(_("Key publishing disabled"), _("No keys available. Generate one or check if your keys aren't expired or revoked!"))); label.set_markup(build_markup_string(_("Key publishing disabled"), _("No keys available. Generate one!")));
return; return;
} }
@ -88,18 +88,6 @@ public class AccountSettingsEntry : Plugins.AccountSettingsEntry {
set_label_active(selected); set_label_active(selected);
combobox.changed.connect(key_changed); combobox.changed.connect(key_changed);
if (account_key != null) {
try {
GPG.Key key_check = GPGHelper.get_public_key(account_key);
if(key_check.expired || key_check.revoked) {
string status_str = key_check.expired ? _("expired!") : _("revoked!");
label.set_markup(build_markup_string(_("Attention required!"), _("Your key %s is %s").printf("<span color='red'><b>"+ key_check.fpr +"</b></span>", status_str) ) );
}
}
catch {
debug("Coudn't check GPG key status.");
}
}
} }
private void populate_list_store() { private void populate_list_store() {

View file

@ -191,12 +191,4 @@ public abstract class Xmpp.XmppStream : Object {
} }
} }
} }
public static bool equals_func(XmppStream str1, XmppStream str2) {
return str1.remote_name.to_string() == str2.remote_name.to_string();
}
public static uint hash_func(XmppStream str) {
return str.remote_name.to_string().hash();
}
} }

View file

@ -25,9 +25,6 @@ namespace Xmpp.Xep.ExternalServiceDiscovery {
service.username = service_node.get_attribute("username", NS_URI); service.username = service_node.get_attribute("username", NS_URI);
service.password = service_node.get_attribute("password", NS_URI); service.password = service_node.get_attribute("password", NS_URI);
string? expires_str = service_node.get_attribute("expires", NS_URI);
if (expires_str != null) service.expires = DateTimeProfiles.parse_string(expires_str);
service.transport = service_node.get_attribute("transport", NS_URI); service.transport = service_node.get_attribute("transport", NS_URI);
service.name = service_node.get_attribute("name", NS_URI); service.name = service_node.get_attribute("name", NS_URI);
string? restricted_str = service_node.get_attribute("restricted", NS_URI); string? restricted_str = service_node.get_attribute("restricted", NS_URI);
@ -44,7 +41,6 @@ namespace Xmpp.Xep.ExternalServiceDiscovery {
public string username { get; set; } public string username { get; set; }
public string password { get; set; } public string password { get; set; }
public DateTime? expires { get; set; }
public string transport { get; set; } public string transport { get; set; }
public string name { get; set; } public string name { get; set; }