Compare commits
191 commits
master
...
master-win
Author | SHA1 | Date | |
---|---|---|---|
d42ea75978 | |||
ecda670d1e | |||
2587a7e6a9 | |||
f1aed531e2 | |||
75092caced | |||
ca1f97e243 | |||
ecb3fb0056 | |||
1a9c55ecc9 | |||
735e6f544a | |||
a3958949f0 | |||
734e1503c7 | |||
bf07ecddb3 | |||
1a73e9d53d | |||
fc8fdc166b | |||
9c15a81b40 | |||
3848cf3129 | |||
43502806bc | |||
b886e2a2f2 | |||
4674e90d16 | |||
a3171e12df | |||
5f500b4d42 | |||
f9fd66dba5 | |||
1c156e8c9f | |||
f6fe383ce8 | |||
49f331627d | |||
7603990740 | |||
7872d21f03 | |||
86182a7db9 | |||
82e6937f21 | |||
3d61f175a6 | |||
471f8c5f4a | |||
fb05c83c8e | |||
ef41c27cb2 | |||
e638ef0694 | |||
a7f7a6d388 | |||
d507808e40 | |||
2d82a4c195 | |||
c29032bcc6 | |||
90bd9df891 | |||
d10badd690 | |||
11828cc2cf | |||
a583a44994 | |||
dd71e943c3 | |||
b8b74817f7 | |||
43fd04ce41 | |||
733d612b18 | |||
5a335f89d3 | |||
c57fc768aa | |||
88a376c1c2 | |||
97753bd5c4 | |||
d7118c1b93 | |||
96fbbdd8bb | |||
4b0c3b8ef0 | |||
ee11a2dbcf | |||
064541dd2b | |||
854818133e | |||
878bf9ac43 | |||
e6a521ada9 | |||
359dcbf70c | |||
c40775b7da | |||
934b492357 | |||
0258980977 | |||
8034a6f344 | |||
c89671af04 | |||
822b91f40c | |||
332216e63c | |||
7b6f3ea9f6 | |||
8988b77d57 | |||
987eb672d5 | |||
1698d15f7d | |||
17c1172d84 | |||
8f8dfa2e70 | |||
e8d84d2eda | |||
f1bcb6604f | |||
c855d5e7cb | |||
ed7c23c8d2 | |||
b1cb64d716 | |||
da424fb73b | |||
39b51b2d4c | |||
7cb6b3f4b3 | |||
15abe70fc6 | |||
ab6ce05aec | |||
c44b1daaf7 | |||
5e50d1d2d7 | |||
d3214188d5 | |||
229ff697c4 | |||
c3624f8490 | |||
597061aed1 | |||
fd035084de | |||
426f997f9b | |||
c60e0a828f | |||
cc0e206c27 | |||
60791cb3f0 | |||
f9a3b28624 | |||
cb3c6874bc | |||
eeda464ca9 | |||
f193948f4e | |||
401c4a1bb1 | |||
34519e96bd | |||
fb754b0d43 | |||
2eb1eea06e | |||
5b40d166d2 | |||
2ad659f777 | |||
b21066c89e | |||
1bd1376cea | |||
f1b5633ce6 | |||
3d9dcbcf87 | |||
8856fcbceb | |||
94944a9e2a | |||
7de1c01fe8 | |||
0f555da7a9 | |||
f2c689fa12 | |||
839d2a5316 | |||
be0e1841b8 | |||
2476b5e04b | |||
bc9b9b95e0 | |||
9d9b9e8e42 | |||
0153953b5d | |||
363b200272 | |||
c6a96fc025 | |||
898470ed23 | |||
6cdaad315a | |||
91d61843f2 | |||
c4f526329d | |||
40bf3d2fd4 | |||
7fd918f32d | |||
1d1b00222f | |||
8df226ec29 | |||
13e0a5c0c4 | |||
ca0cab0e36 | |||
ae9671716f | |||
ce0deed0dc | |||
95051d304a | |||
915dd4c738 | |||
e3356bb3aa | |||
03774a3756 | |||
2d63c8ae77 | |||
96f96ead7e | |||
5f2e636868 | |||
d8bb9897a4 | |||
08f2391acc | |||
eae628758c | |||
931f09504d | |||
5702b323c9 | |||
198bce4a84 | |||
8553a7cd86 | |||
642ed6ab1b | |||
d36de2b9ea | |||
49978edebf | |||
65a26bce53 | |||
1d4bb774a5 | |||
3dd19fad71 | |||
4a3306b479 | |||
0b9bebd97e | |||
24890ca38a | |||
50b2a0dc0a | |||
a6515ed826 | |||
e7fd7f4726 | |||
9022ac596b | |||
823df3ed70 | |||
6d5ee03e9e | |||
1673ec3481 | |||
16d0cc6fd9 | |||
03f17b8f39 | |||
25673ab145 | |||
8cb15fc325 | |||
281a84a14c | |||
e2fd821bb4 | |||
0d384f83ae | |||
1841b348f1 | |||
5f5b8fdfa0 | |||
eb7cf3297c | |||
5d551360df | |||
a94acccd1d | |||
d0d676e72d | |||
81721307ca | |||
2d73f97d34 | |||
e24aa9aabc | |||
26a85ac109 | |||
8adf6731e7 | |||
9154edaee1 | |||
fd916bd6e6 | |||
48619ee84d | |||
70900cd73e | |||
64260ee8c0 | |||
246000ce6a | |||
9779abe701 | |||
3ffec591a9 | |||
7d6b9e7f4c | |||
43f118bd4e | |||
057a72cd9f |
26
.github/workflows/build-win64.yml
vendored
Normal file
26
.github/workflows/build-win64.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
name: Build for Windows
|
||||||
|
on: [pull_request, push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- uses: msys2/setup-msys2@v2
|
||||||
|
with:
|
||||||
|
msystem: MINGW64
|
||||||
|
update: true
|
||||||
|
install: git
|
||||||
|
- run: git config --global core.autocrlf input
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Build Dino
|
||||||
|
run: |
|
||||||
|
msys2 -c './build-win64.sh --prepare'
|
||||||
|
msys2 -c './build-win64.sh'
|
||||||
|
- name: Build Dino Installer
|
||||||
|
run: |
|
||||||
|
msys2 -c './build-win64.sh --build-installer'
|
||||||
|
- name: Upload Dino Installer
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: dino-installer
|
||||||
|
path: windows-installer/dino-installer.exe
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
|
@ -9,7 +9,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- 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 libwebrtc-audio-processing-dev libadwaita-1-dev libsignal-protocol-c-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 libwebrtc-audio-processing-dev libadwaita-1-dev libsignal-protocol-c-dev libcanberra-dev
|
||||||
- run: ./configure --with-tests --with-libsignal-in-tree
|
- run: ./configure --with-tests --with-libsignal-in-tree
|
||||||
- run: make
|
- run: make
|
||||||
- run: build/xmpp-vala-test
|
- run: build/xmpp-vala-test
|
||||||
|
@ -34,6 +34,7 @@ jobs:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
submodules: true
|
||||||
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6.1
|
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6.1
|
||||||
with:
|
with:
|
||||||
manifest-path: im.dino.Dino.json
|
manifest-path: im.dino.Dino.json
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -6,3 +6,7 @@ Makefile
|
||||||
.idea
|
.idea
|
||||||
.sqlite3
|
.sqlite3
|
||||||
gschemas.compiled
|
gschemas.compiled
|
||||||
|
windows-installer/win64-dist/
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
.flatpak-builder
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "shared-modules"]
|
||||||
|
path = shared-modules
|
||||||
|
url = https://github.com/flathub/shared-modules.git
|
|
@ -12,6 +12,12 @@ endif ()
|
||||||
|
|
||||||
# Prepare Plugins
|
# Prepare Plugins
|
||||||
set(DEFAULT_PLUGINS omemo;openpgp;http-files;ice;rtp)
|
set(DEFAULT_PLUGINS omemo;openpgp;http-files;ice;rtp)
|
||||||
|
if (WIN32)
|
||||||
|
list(APPEND DEFAULT_PLUGINS win32-fonts windows-notification)
|
||||||
|
else()
|
||||||
|
list(APPEND DEFAULT_PLUGINS phone-ringer)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach (plugin ${DEFAULT_PLUGINS})
|
foreach (plugin ${DEFAULT_PLUGINS})
|
||||||
if ("$CACHE{DINO_PLUGIN_ENABLED_${plugin}}" STREQUAL "")
|
if ("$CACHE{DINO_PLUGIN_ENABLED_${plugin}}" STREQUAL "")
|
||||||
if (NOT DEFINED DINO_PLUGIN_ENABLED_${plugin}})
|
if (NOT DEFINED DINO_PLUGIN_ENABLED_${plugin}})
|
||||||
|
@ -176,6 +182,11 @@ if (NOT NO_DEBUG)
|
||||||
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} -g")
|
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} -g")
|
||||||
endif (NOT NO_DEBUG)
|
endif (NOT NO_DEBUG)
|
||||||
|
|
||||||
|
if (WIN32)
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=1")
|
||||||
|
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} --define=_WIN32")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
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})
|
||||||
|
|
||||||
|
|
56
README-WIN64.md
Normal file
56
README-WIN64.md
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
![Dino (WIN64)](https://dino.im/img/readme_header.svg)
|
||||||
|
=======
|
||||||
|
|
||||||
|
![screenshots](https://dino.im/img/screenshot-main.png)
|
||||||
|
|
||||||
|
Build on Windows (x86_64)
|
||||||
|
------------
|
||||||
|
- Install and configure the [MSYS2](https://www.msys2.org/) package;
|
||||||
|
- Go to `MINGW64` environment;
|
||||||
|
- Clone project:
|
||||||
|
```sh
|
||||||
|
git clone https://github.com/mxlgv/dino && cd dino
|
||||||
|
```
|
||||||
|
- Run the script to install dependencies:
|
||||||
|
```sh
|
||||||
|
./build-win64.sh --prepare
|
||||||
|
```
|
||||||
|
- Start the build (the builded distribution is available in the `windows-installer/dist-win64` folder):
|
||||||
|
```sh
|
||||||
|
./build-win64.sh
|
||||||
|
```
|
||||||
|
Note: the build script has some other options, their description can be found using the `--help`.
|
||||||
|
|
||||||
|
Build Windows Installer (NSIS)
|
||||||
|
------------
|
||||||
|
Before this, you must build the project according to the instructions above. It's worth making sure that `windows-installer/dist-win64` is not empty.
|
||||||
|
Now you should run:
|
||||||
|
```sh
|
||||||
|
./build-win64.sh --build-installer
|
||||||
|
```
|
||||||
|
|
||||||
|
The builded installer will be available in the directory `windows-installer/dino-installer.exe`.
|
||||||
|
|
||||||
|
Resources
|
||||||
|
---------
|
||||||
|
- Check out the [Dino website](https://dino.im).
|
||||||
|
- Join our XMPP channel at `chat@dino.im`.
|
||||||
|
- The [wiki](https://github.com/dino/dino/wiki) provides additional information.
|
||||||
|
|
||||||
|
License
|
||||||
|
-------
|
||||||
|
Dino - Modern Jabber/XMPP Client using GTK+/Vala
|
||||||
|
Copyright (C) 2016-2023 Dino contributors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
25
build-flatpack.sh
Normal file
25
build-flatpack.sh
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
getFlatpackDependencies(){
|
||||||
|
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
|
||||||
|
flatpak install flathub org.gnome.Sdk//44
|
||||||
|
flatpak install flathub org.gnome.Platform//44
|
||||||
|
}
|
||||||
|
|
||||||
|
prepareModules(){
|
||||||
|
git submodule init
|
||||||
|
git submodule update
|
||||||
|
}
|
||||||
|
|
||||||
|
build(){
|
||||||
|
FP_TEMP_BUILD_DIR=$(mktemp -d)
|
||||||
|
FP_OUTDIR="builds"
|
||||||
|
flatpak-builder ${FP_TEMP_BUILD_DIR} im.dino.Dino.json
|
||||||
|
flatpak build-export $FP_OUTDIR $FP_TEMP_BUILD_DIR
|
||||||
|
flatpak build-bundle $FP_OUTDIR dino.flatpak
|
||||||
|
}
|
||||||
|
|
||||||
|
getFlatpackDependencies
|
||||||
|
prepareModules
|
||||||
|
build
|
182
build-win64.sh
Normal file
182
build-win64.sh
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
DIST_DIR="$PWD/windows-installer/win64-dist"
|
||||||
|
JOBS=$NUMBER_OF_PROCESSORS
|
||||||
|
|
||||||
|
msg()
|
||||||
|
{
|
||||||
|
echo -e "\e[32m$1\e[0m"
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal()
|
||||||
|
{
|
||||||
|
echo -e "\e[31m$1\e[0m"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
download_yolort()
|
||||||
|
{
|
||||||
|
file_name=cppwinrt-2.0.210122.3+windows-10.0.19041+yolort-835cd4e.zip
|
||||||
|
yolort_dir="$PWD/plugins/windows-notification/yolort"
|
||||||
|
|
||||||
|
rm -rf "$yolort_dir"
|
||||||
|
mkdir "$yolort_dir"
|
||||||
|
curl -L -o "$file_name" "https://github.com/LAGonauta/YoloRT/releases/download/v1.0.0/$file_name"
|
||||||
|
echo "675a6d943c97b4acdbfaa473f68d3241d1798b31a67b5529c8d29fc0176a1707 $file_name" | sha256sum --check --status
|
||||||
|
unzip -o "$file_name" -d "$yolort_dir"
|
||||||
|
rm -f "$file_name"
|
||||||
|
}
|
||||||
|
|
||||||
|
prepare()
|
||||||
|
{
|
||||||
|
msg "Installing MINGW64 build dependencies"
|
||||||
|
|
||||||
|
pacman -S --needed --noconfirm \
|
||||||
|
mingw64/mingw-w64-x86_64-gcc \
|
||||||
|
mingw64/mingw-w64-x86_64-cmake \
|
||||||
|
mingw64/mingw-w64-x86_64-ninja \
|
||||||
|
mingw64/mingw-w64-x86_64-gtk4 \
|
||||||
|
mingw64/mingw-w64-x86_64-libadwaita \
|
||||||
|
mingw64/mingw-w64-x86_64-sqlite3 \
|
||||||
|
mingw64/mingw-w64-x86_64-openssl \
|
||||||
|
mingw64/mingw-w64-x86_64-libgcrypt \
|
||||||
|
mingw64/mingw-w64-x86_64-libgee \
|
||||||
|
mingw64/mingw-w64-x86_64-vala \
|
||||||
|
mingw64/mingw-w64-x86_64-gsettings-desktop-schemas \
|
||||||
|
mingw64/mingw-w64-x86_64-qrencode \
|
||||||
|
mingw64/mingw-w64-x86_64-ntldd-git \
|
||||||
|
mingw64/mingw-w64-x86_64-gpgme \
|
||||||
|
mingw64/mingw-w64-x86_64-fontconfig \
|
||||||
|
mingw64/mingw-w64-x86_64-iso-codes \
|
||||||
|
mingw64/mingw-w64-x86_64-gstreamer \
|
||||||
|
mingw64/mingw-w64-x86_64-gst-plugins-bad \
|
||||||
|
mingw64/mingw-w64-x86_64-gst-plugins-good \
|
||||||
|
mingw64/mingw-w64-x86_64-gst-plugins-base \
|
||||||
|
mingw64/mingw-w64-x86_64-gst-plugins-ugly \
|
||||||
|
mingw64/mingw-w64-x86_64-nsis \
|
||||||
|
mingw64/mingw-w64-x86_64-libsignal-protocol-c \
|
||||||
|
mingw64/mingw-w64-x86_64-icu \
|
||||||
|
mingw64/mingw-w64-x86_64-webrtc-audio-processing \
|
||||||
|
git \
|
||||||
|
make \
|
||||||
|
unzip \
|
||||||
|
curl
|
||||||
|
|
||||||
|
msg "Successfully installed!"
|
||||||
|
|
||||||
|
msg "Download YoloRT headers"
|
||||||
|
download_yolort
|
||||||
|
msg "Successfully downloaded!"
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
configure()
|
||||||
|
{
|
||||||
|
msg "Running configuration for Windows"
|
||||||
|
./configure --program-prefix="$DIST_DIR" --no-debug --release --disable-fast-vapi --with-libsoup3
|
||||||
|
msg "Configured!"
|
||||||
|
}
|
||||||
|
|
||||||
|
build()
|
||||||
|
{
|
||||||
|
msg "Started building on $JOBS threads"
|
||||||
|
make -j"$JOBS"
|
||||||
|
msg "Successfully builded!"
|
||||||
|
}
|
||||||
|
|
||||||
|
dist_install()
|
||||||
|
{
|
||||||
|
msg "Installing Dino in '$DIST_DIR'!"
|
||||||
|
make install
|
||||||
|
|
||||||
|
msg "Copying MINGW64 dependencies"
|
||||||
|
cp /mingw64/bin/gdbus.exe "$DIST_DIR/bin"
|
||||||
|
cp /mingw64/bin/gspawn-win64-helper.exe "$DIST_DIR/bin"
|
||||||
|
|
||||||
|
cp /mingw64/bin/libcrypto-*-x64.dll "$DIST_DIR/bin/"
|
||||||
|
cp -r /mingw64/lib/gstreamer-1.0 "$DIST_DIR/lib"
|
||||||
|
mkdir -p "$DIST_DIR/lib/gdk-pixbuf-2.0/" && cp -r /mingw64/lib/gdk-pixbuf-2.0 "$DIST_DIR/lib/"
|
||||||
|
mkdir -p "$DIST_DIR/lib/gio/" && cp -r /mingw64/lib/gio "$DIST_DIR/lib/"
|
||||||
|
|
||||||
|
list=`find "$DIST_DIR" -type f \( -name "*.exe" -o -name "*.dll" \) -exec \
|
||||||
|
ntldd -R {} + | \
|
||||||
|
grep "mingw64" | \
|
||||||
|
cut -f1 -d "=" | sort | uniq`
|
||||||
|
for a in $list; do
|
||||||
|
cp -fv "/mingw64/bin/$a" "$DIST_DIR/bin/"
|
||||||
|
done
|
||||||
|
|
||||||
|
msg "Removing debug information from all EXE and DLL files"
|
||||||
|
find "$DIST_DIR" -iname "*.exe" -exec strip -s {} +
|
||||||
|
find "$DIST_DIR" -iname "*.dll" -exec strip -s {} +
|
||||||
|
|
||||||
|
find "$DIST_DIR" -iname "*.a" -exec rm {} +
|
||||||
|
|
||||||
|
msg "Removing redudant header files"
|
||||||
|
rm -rf "$DIST_DIR/include"
|
||||||
|
|
||||||
|
msg "Copy LICENSE"
|
||||||
|
cp -f "$PWD/LICENSE" "$DIST_DIR/LICENSE"
|
||||||
|
|
||||||
|
msg "Copy icons, themes, locales and fonts"
|
||||||
|
cp -f "$PWD/main/dino.ico" "$DIST_DIR/dino.ico"
|
||||||
|
cp -rf "/mingw64/share/xml" "$DIST_DIR/share"
|
||||||
|
mkdir -p "$DIST_DIR/etc/fonts" && cp -r /mingw64/etc/fonts "$DIST_DIR/etc/"
|
||||||
|
mkdir -p "$DIST_DIR/share/icons" && cp -r /mingw64/share/icons "$DIST_DIR/share/"
|
||||||
|
mkdir -p "$DIST_DIR/share/glib-2.0/schemas" && cp -rf /mingw64/share/glib-2.0/schemas "$DIST_DIR/share/glib-2.0/"
|
||||||
|
|
||||||
|
msg "Successfully installed!"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_installer()
|
||||||
|
{
|
||||||
|
msg "Building an installer for Windows using NSIS"
|
||||||
|
cd windows-installer
|
||||||
|
makensis dino.nsi
|
||||||
|
msg "Installer successfully builded!"
|
||||||
|
cd ..
|
||||||
|
}
|
||||||
|
|
||||||
|
clean()
|
||||||
|
{
|
||||||
|
rm -rf build "$DIST_DIR"
|
||||||
|
msg "Build artifacts removed successfull!"
|
||||||
|
}
|
||||||
|
|
||||||
|
help()
|
||||||
|
{
|
||||||
|
cat << EOF
|
||||||
|
usage: $0 [OPTION]
|
||||||
|
--prepare install build dependencies
|
||||||
|
--configure configure the project
|
||||||
|
--build build the project
|
||||||
|
--dist-install install the builded project
|
||||||
|
--build-installer build installer (using NSIS)
|
||||||
|
--clean remove build artifacts
|
||||||
|
--help show this help
|
||||||
|
|
||||||
|
Running without parameters is equivalent to running:
|
||||||
|
'--configure', '--build' and '--dist-install'
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$(uname)" != "MINGW64_NT"* ]]; then
|
||||||
|
fatal "This is not a MINGW64 environment!"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
"--prepare" ) prepare ;;
|
||||||
|
"--configure" ) configure ;;
|
||||||
|
"--build" ) build ;;
|
||||||
|
"--dist-install" ) dist_install ;;
|
||||||
|
"--build-installer") build_installer ;;
|
||||||
|
"--clean" ) clean ;;
|
||||||
|
"--help" ) help ;;
|
||||||
|
"" )
|
||||||
|
configure
|
||||||
|
build
|
||||||
|
dist_install
|
||||||
|
;;
|
||||||
|
*) fatal "Unknown argument!"
|
||||||
|
esac
|
|
@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback name)
|
||||||
# Found via pkg-config, using its result values
|
# Found via pkg-config, using its result values
|
||||||
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})
|
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})
|
||||||
|
|
||||||
|
if(MINGW)
|
||||||
|
set(MINGWLIBPATH ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
||||||
|
endif(MINGW)
|
||||||
|
|
||||||
# Try to find real file name of libraries
|
# Try to find real file name of libraries
|
||||||
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
|
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
|
||||||
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS})
|
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS} ${MINGWLIBPATH})
|
||||||
mark_as_advanced(${name}_${lib}_LIBRARY)
|
mark_as_advanced(${name}_${lib}_LIBRARY)
|
||||||
if(NOT ${name}_${lib}_LIBRARY)
|
if(NOT ${name}_${lib}_LIBRARY)
|
||||||
|
message(${name} ": " ${lib} " library not found")
|
||||||
unset(${name}_FOUND)
|
unset(${name}_FOUND)
|
||||||
endif(NOT ${name}_${lib}_LIBRARY)
|
endif(NOT ${name}_${lib}_LIBRARY)
|
||||||
endforeach(lib)
|
endforeach(lib)
|
||||||
|
|
|
@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback_on_config_script name)
|
||||||
# Found via pkg-config, using it's result values
|
# Found via pkg-config, using it's result values
|
||||||
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})
|
set(${name}_FOUND ${${name}_PKG_CONFIG_FOUND})
|
||||||
|
|
||||||
|
if(MINGW)
|
||||||
|
set(MINGWLIBPATH ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
||||||
|
endif(MINGW)
|
||||||
|
|
||||||
# Try to find real file name of libraries
|
# Try to find real file name of libraries
|
||||||
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
|
foreach(lib ${${name}_PKG_CONFIG_LIBRARIES})
|
||||||
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS})
|
find_library(${name}_${lib}_LIBRARY ${lib} HINTS ${${name}_PKG_CONFIG_LIBRARY_DIRS} ${MINGWLIBPATH})
|
||||||
mark_as_advanced(${name}_${lib}_LIBRARY)
|
mark_as_advanced(${name}_${lib}_LIBRARY)
|
||||||
if(NOT ${name}_${lib}_LIBRARY)
|
if(NOT ${name}_${lib}_LIBRARY)
|
||||||
|
message(${name} ": " ${lib} " library not found")
|
||||||
unset(${name}_FOUND)
|
unset(${name}_FOUND)
|
||||||
endif(NOT ${name}_${lib}_LIBRARY)
|
endif(NOT ${name}_${lib}_LIBRARY)
|
||||||
endforeach(lib)
|
endforeach(lib)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
"--talk-name=org.freedesktop.Notifications"
|
"--talk-name=org.freedesktop.Notifications"
|
||||||
],
|
],
|
||||||
"modules": [
|
"modules": [
|
||||||
|
"shared-modules/libcanberra/libcanberra.json",
|
||||||
{
|
{
|
||||||
"name": "libsignal-protocol-c",
|
"name": "libsignal-protocol-c",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
|
|
|
@ -304,6 +304,24 @@ public class AvatarManager : StreamInteractionModule, Object {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string? get_avatar_filepath(Account account, Jid jid_) {
|
||||||
|
Jid jid = jid_;
|
||||||
|
if (!stream_interactor.get_module(MucManager.IDENTITY).is_groupchat_occupant(jid_, account)) {
|
||||||
|
jid = jid_.bare_jid;
|
||||||
|
}
|
||||||
|
|
||||||
|
string? hash = null;
|
||||||
|
if (user_avatars.has_key(jid)) {
|
||||||
|
hash = user_avatars[jid];
|
||||||
|
} else if (vcard_avatars.has_key(jid)) {
|
||||||
|
hash = vcard_avatars[jid];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hash == null) return null;
|
||||||
|
|
||||||
|
return Path.build_filename(folder, hash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,7 @@ public class FileManager : StreamInteractionModule, Object {
|
||||||
try {
|
try {
|
||||||
FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
|
FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
|
||||||
file_transfer.file_name = file_info.get_display_name();
|
file_transfer.file_name = file_info.get_display_name();
|
||||||
file_transfer.mime_type = file_info.get_content_type();
|
file_transfer.mime_type = Util.get_content_type(file_info);
|
||||||
file_transfer.size = (int)file_info.get_size();
|
file_transfer.size = (int)file_info.get_size();
|
||||||
file_transfer.input_stream = yield file.read_async();
|
file_transfer.input_stream = yield file.read_async();
|
||||||
|
|
||||||
|
@ -259,9 +259,16 @@ public class FileManager : StreamInteractionModule, Object {
|
||||||
file_transfer.input_stream = yield file.read_async();
|
file_transfer.input_stream = yield file.read_async();
|
||||||
|
|
||||||
FileInfo file_info = file_transfer.get_file().query_info("*", FileQueryInfoFlags.NONE);
|
FileInfo file_info = file_transfer.get_file().query_info("*", FileQueryInfoFlags.NONE);
|
||||||
file_transfer.mime_type = file_info.get_content_type();
|
file_transfer.mime_type = Util.get_content_type(file_info);
|
||||||
|
|
||||||
file_transfer.state = FileTransfer.State.COMPLETE;
|
file_transfer.state = FileTransfer.State.COMPLETE;
|
||||||
|
|
||||||
|
#if _WIN32 // Add Zone.Identifier so Windows knows this file was downloaded from the internet
|
||||||
|
var file_alternate_stream = File.new_for_path(Path.build_filename(get_storage_dir(), filename + ":Zone.Identifier"));
|
||||||
|
var os_alternate_stream = file_alternate_stream.create(FileCreateFlags.REPLACE_DESTINATION);
|
||||||
|
os_alternate_stream.write("[ZoneTransfer]\r\nZoneId=3".data);
|
||||||
|
#endif
|
||||||
|
|
||||||
} catch (Error e) {
|
} catch (Error e) {
|
||||||
warning("Error downloading file: %s", e.message);
|
warning("Error downloading file: %s", e.message);
|
||||||
file_transfer.state = FileTransfer.State.FAILED;
|
file_transfer.state = FileTransfer.State.FAILED;
|
||||||
|
|
|
@ -120,6 +120,37 @@ public class Dino.HistorySync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void fetch_history(Account account, Jid target, Cancellable? cancellable = null) {
|
||||||
|
debug("Fetch history for %s", target.to_string());
|
||||||
|
|
||||||
|
RowOption latest_row_opt = db.mam_catchup.select()
|
||||||
|
.with(db.mam_catchup.account_id, "=", account.id)
|
||||||
|
.with(db.mam_catchup.server_jid, "=", target.to_string())
|
||||||
|
.with(db.mam_catchup.to_time, ">=", (long) new DateTime.from_unix_utc(0).to_unix())
|
||||||
|
.order_by(db.mam_catchup.to_time, "DESC")
|
||||||
|
.single().row();
|
||||||
|
Row? latest_row = latest_row_opt.is_present() ? latest_row_opt.inner : null;
|
||||||
|
|
||||||
|
int? db_id = null;
|
||||||
|
string? latest_id = null;
|
||||||
|
if (latest_row != null) {
|
||||||
|
// Local mam catchup data exists so we can filter messages based on the latest id
|
||||||
|
db_id = latest_row[db.mam_catchup.id];
|
||||||
|
latest_id = latest_row[db.mam_catchup.from_id];
|
||||||
|
}
|
||||||
|
|
||||||
|
DateTime latest_time = new DateTime.now();
|
||||||
|
Xmpp.MessageArchiveManagement.V2.MamQueryParams query_params;
|
||||||
|
query_params = new Xmpp.MessageArchiveManagement.V2.MamQueryParams.query_before(target, latest_time, latest_id);
|
||||||
|
|
||||||
|
if (db_id == null) {
|
||||||
|
query_params.mam_server = account.bare_jid;
|
||||||
|
query_params.with = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield fetch_query(account, query_params, db_id, cancellable);
|
||||||
|
}
|
||||||
|
|
||||||
public async void fetch_everything(Account account, Jid mam_server, Cancellable? cancellable = null, DateTime until_earliest_time = new DateTime.from_unix_utc(0)) {
|
public async void fetch_everything(Account account, Jid mam_server, Cancellable? cancellable = null, DateTime until_earliest_time = new DateTime.from_unix_utc(0)) {
|
||||||
debug("Fetch everything for %s %s", mam_server.to_string(), until_earliest_time != null ? @"(until $until_earliest_time)" : "");
|
debug("Fetch everything for %s %s", mam_server.to_string(), until_earliest_time != null ? @"(until $until_earliest_time)" : "");
|
||||||
RowOption latest_row_opt = db.mam_catchup.select()
|
RowOption latest_row_opt = db.mam_catchup.select()
|
||||||
|
@ -321,7 +352,7 @@ public class Dino.HistorySync {
|
||||||
* Iteratively fetches all pages returned for a query (until a PageResult other than MorePagesAvailable is returned)
|
* Iteratively fetches all pages returned for a query (until a PageResult other than MorePagesAvailable is returned)
|
||||||
* @return The last PageRequestResult result
|
* @return The last PageRequestResult result
|
||||||
**/
|
**/
|
||||||
private async PageRequestResult fetch_query(Account account, Xmpp.MessageArchiveManagement.V2.MamQueryParams query_params, int db_id, Cancellable? cancellable = null) {
|
private async PageRequestResult fetch_query(Account account, Xmpp.MessageArchiveManagement.V2.MamQueryParams query_params, int? db_id, Cancellable? cancellable = null) {
|
||||||
debug("[%s | %s] Fetch query %s - %s", account.bare_jid.to_string(), query_params.mam_server.to_string(), query_params.start != null ? query_params.start.to_string() : "", query_params.end != null ? query_params.end.to_string() : "");
|
debug("[%s | %s] Fetch query %s - %s", account.bare_jid.to_string(), query_params.mam_server.to_string(), query_params.start != null ? query_params.start.to_string() : "", query_params.end != null ? query_params.end.to_string() : "");
|
||||||
PageRequestResult? page_result = null;
|
PageRequestResult? page_result = null;
|
||||||
do {
|
do {
|
||||||
|
@ -333,6 +364,8 @@ public class Dino.HistorySync {
|
||||||
string earliest_mam_id = page_result.query_result.first;
|
string earliest_mam_id = page_result.query_result.first;
|
||||||
long earliest_mam_time = (long)mam_times[account][earliest_mam_id].to_unix();
|
long earliest_mam_time = (long)mam_times[account][earliest_mam_id].to_unix();
|
||||||
|
|
||||||
|
if (db_id != null) {
|
||||||
|
// Update local mam catchup data if it exists
|
||||||
debug("Updating %s to %s, %s", query_params.mam_server.to_string(), earliest_mam_time.to_string(), earliest_mam_id);
|
debug("Updating %s to %s, %s", query_params.mam_server.to_string(), earliest_mam_time.to_string(), earliest_mam_id);
|
||||||
var query = db.mam_catchup.update()
|
var query = db.mam_catchup.update()
|
||||||
.with(db.mam_catchup.id, "=", db_id)
|
.with(db.mam_catchup.id, "=", db_id)
|
||||||
|
@ -344,6 +377,8 @@ public class Dino.HistorySync {
|
||||||
query.set(db.mam_catchup.from_end, true);
|
query.set(db.mam_catchup.from_end, true);
|
||||||
}
|
}
|
||||||
query.perform();
|
query.perform();
|
||||||
|
}
|
||||||
|
|
||||||
} while (page_result.page_result == PageResult.MorePagesAvailable);
|
} while (page_result.page_result == PageResult.MorePagesAvailable);
|
||||||
|
|
||||||
return page_result;
|
return page_result;
|
||||||
|
|
|
@ -12,9 +12,7 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
public signal void notify_content_item(ContentItem content_item, Conversation conversation);
|
public signal void notify_content_item(ContentItem content_item, Conversation conversation);
|
||||||
|
|
||||||
private StreamInteractor stream_interactor;
|
private StreamInteractor stream_interactor;
|
||||||
private Future<NotificationProvider> notifier;
|
private Gee.List<Promise<NotificationProvider>> promises = new ArrayList<Promise<NotificationProvider>>();
|
||||||
private Promise<NotificationProvider> notifier_promise;
|
|
||||||
private bool notifier_outstanding = true;
|
|
||||||
|
|
||||||
public static void start(StreamInteractor stream_interactor) {
|
public static void start(StreamInteractor stream_interactor) {
|
||||||
NotificationEvents m = new NotificationEvents(stream_interactor);
|
NotificationEvents m = new NotificationEvents(stream_interactor);
|
||||||
|
@ -31,18 +29,16 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
stream_interactor.get_module(MucManager.IDENTITY).voice_request_received.connect((account, room_jid, from_jid, nick) => on_voice_request_received.begin(account, room_jid, from_jid, nick));
|
stream_interactor.get_module(MucManager.IDENTITY).voice_request_received.connect((account, room_jid, from_jid, nick) => on_voice_request_received.begin(account, room_jid, from_jid, nick));
|
||||||
|
|
||||||
stream_interactor.get_module(Calls.IDENTITY).call_incoming.connect((call, state, conversation, video, multiparty) => on_call_incoming.begin(call, state, conversation, video, multiparty));
|
stream_interactor.get_module(Calls.IDENTITY).call_incoming.connect((call, state, conversation, video, multiparty) => on_call_incoming.begin(call, state, conversation, video, multiparty));
|
||||||
|
stream_interactor.get_module(Calls.IDENTITY).call_outgoing.connect((call, state, conversation) => on_call_outgoing.begin(call));
|
||||||
|
|
||||||
stream_interactor.connection_manager.connection_error.connect((account, error) => on_connection_error.begin(account, error));
|
stream_interactor.connection_manager.connection_error.connect((account, error) => on_connection_error.begin(account, error));
|
||||||
stream_interactor.get_module(ChatInteraction.IDENTITY).focused_in.connect((conversation) => on_focused_in.begin(conversation));
|
stream_interactor.get_module(ChatInteraction.IDENTITY).focused_in.connect((conversation) => on_focused_in.begin(conversation));
|
||||||
|
|
||||||
notifier_promise = new Promise<NotificationProvider>();
|
|
||||||
notifier = notifier_promise.future;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async void register_notification_provider(NotificationProvider notification_provider) {
|
public async void register_notification_provider(NotificationProvider notification_provider) {
|
||||||
if (notifier_outstanding || (yield notifier.wait_async()).get_priority() < notification_provider.get_priority()) {
|
var promise = new Promise<NotificationProvider>();
|
||||||
notifier_outstanding = false;
|
promise.set_value(notification_provider);
|
||||||
notifier_promise.set_value(notification_provider);
|
promises.add(promise);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void on_content_item_received(ContentItem item, Conversation conversation) {
|
private async void on_content_item_received(ContentItem item, Conversation conversation) {
|
||||||
|
@ -77,9 +73,11 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
|
|
||||||
notify_content_item(item, conversation);
|
notify_content_item(item, conversation);
|
||||||
if (notify != Conversation.NotifySetting.OFF) {
|
if (notify != Conversation.NotifySetting.OFF) {
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_message(message, conversation, conversation_display_name, participant_display_name);
|
yield notifier.notify_message(message, conversation, conversation_display_name, participant_display_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case FileItem.TYPE:
|
case FileItem.TYPE:
|
||||||
FileTransfer file_transfer = ((FileItem) item).file_transfer;
|
FileTransfer file_transfer = ((FileItem) item).file_transfer;
|
||||||
|
@ -91,9 +89,11 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
|
|
||||||
notify_content_item(item, conversation);
|
notify_content_item(item, conversation);
|
||||||
if (notify != Conversation.NotifySetting.OFF) {
|
if (notify != Conversation.NotifySetting.OFF) {
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_file(file_transfer, conversation, is_image, conversation_display_name, participant_display_name);
|
yield notifier.notify_file(file_transfer, conversation, is_image, conversation_display_name, participant_display_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CallItem.TYPE:
|
case CallItem.TYPE:
|
||||||
// handled in `on_call_incoming`
|
// handled in `on_call_incoming`
|
||||||
|
@ -105,23 +105,28 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(room_jid, account, Conversation.Type.GROUPCHAT);
|
Conversation? conversation = stream_interactor.get_module(ConversationManager.IDENTITY).get_conversation(room_jid, account, Conversation.Type.GROUPCHAT);
|
||||||
if (conversation == null) return;
|
if (conversation == null) return;
|
||||||
|
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_voice_request(conversation, from_jid);
|
yield notifier.notify_voice_request(conversation, from_jid);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void on_received_subscription_request(Jid jid, Account account) {
|
private async void on_received_subscription_request(Jid jid, Account account) {
|
||||||
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.CHAT);
|
Conversation conversation = stream_interactor.get_module(ConversationManager.IDENTITY).create_conversation(jid, account, Conversation.Type.CHAT);
|
||||||
if (stream_interactor.get_module(ChatInteraction.IDENTITY).is_active_focus(conversation)) return;
|
if (stream_interactor.get_module(ChatInteraction.IDENTITY).is_active_focus(conversation)) return;
|
||||||
|
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_subscription_request(conversation);
|
yield notifier.notify_subscription_request(conversation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void on_call_incoming(Call call, CallState call_state, Conversation conversation, bool video, bool multiparty) {
|
private async void on_call_incoming(Call call, CallState call_state, Conversation conversation, bool video, bool multiparty) {
|
||||||
if (!stream_interactor.get_module(Calls.IDENTITY).can_we_do_calls(call.account)) return;
|
if (!stream_interactor.get_module(Calls.IDENTITY).can_we_do_calls(call.account)) return;
|
||||||
string conversation_display_name = get_conversation_display_name(stream_interactor, conversation, null);
|
string conversation_display_name = get_conversation_display_name(stream_interactor, conversation, null);
|
||||||
|
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_call(call, conversation, video, multiparty, conversation_display_name);
|
yield notifier.notify_call(call, conversation, video, multiparty, conversation_display_name);
|
||||||
call.notify["state"].connect(() => {
|
call.notify["state"].connect(() => {
|
||||||
if (call.state != Call.State.RINGING) {
|
if (call.state != Call.State.RINGING) {
|
||||||
|
@ -129,6 +134,19 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void on_call_outgoing(Call call) {
|
||||||
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
|
yield notifier.notify_dialing();
|
||||||
|
call.notify["state"].connect(() => {
|
||||||
|
if (call.state != Call.State.ESTABLISHING) {
|
||||||
|
notifier.retract_dialing.begin();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void on_invite_received(Account account, Jid room_jid, Jid from_jid, string? password, string? reason) {
|
private async void on_invite_received(Account account, Jid room_jid, Jid from_jid, string? password, string? reason) {
|
||||||
string inviter_display_name;
|
string inviter_display_name;
|
||||||
|
@ -139,21 +157,28 @@ public class NotificationEvents : StreamInteractionModule, Object {
|
||||||
Conversation direct_conversation = new Conversation(from_jid, account, Conversation.Type.CHAT);
|
Conversation direct_conversation = new Conversation(from_jid, account, Conversation.Type.CHAT);
|
||||||
inviter_display_name = get_participant_display_name(stream_interactor, direct_conversation, from_jid);
|
inviter_display_name = get_participant_display_name(stream_interactor, direct_conversation, from_jid);
|
||||||
}
|
}
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
|
||||||
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_muc_invite(account, room_jid, from_jid, inviter_display_name);
|
yield notifier.notify_muc_invite(account, room_jid, from_jid, inviter_display_name);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void on_connection_error(Account account, ConnectionManager.ConnectionError error) {
|
private async void on_connection_error(Account account, ConnectionManager.ConnectionError error) {
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.notify_connection_error(account, error);
|
yield notifier.notify_connection_error(account, error);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void on_focused_in(Conversation conversation) {
|
private async void on_focused_in(Conversation conversation) {
|
||||||
NotificationProvider notifier = yield notifier.wait_async();
|
foreach(var promise in promises) {
|
||||||
|
NotificationProvider notifier = yield promise.future.wait_async();
|
||||||
yield notifier.retract_content_item_notifications();
|
yield notifier.retract_content_item_notifications();
|
||||||
yield notifier.retract_conversation_notifications(conversation);
|
yield notifier.retract_conversation_notifications(conversation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public interface NotificationProvider : Object {
|
public interface NotificationProvider : Object {
|
||||||
public abstract double get_priority();
|
public abstract double get_priority();
|
||||||
|
@ -162,6 +187,8 @@ public interface NotificationProvider : Object {
|
||||||
public abstract async void notify_file(FileTransfer file_transfer, Conversation conversation, bool is_image, string conversation_display_name, string? participant_display_name);
|
public abstract async void notify_file(FileTransfer file_transfer, Conversation conversation, bool is_image, string conversation_display_name, string? participant_display_name);
|
||||||
public abstract async void notify_call(Call call, Conversation conversation, bool video, bool multiparty, string conversation_display_name);
|
public abstract async void notify_call(Call call, Conversation conversation, bool video, bool multiparty, string conversation_display_name);
|
||||||
public abstract async void retract_call_notification(Call call, Conversation conversation);
|
public abstract async void retract_call_notification(Call call, Conversation conversation);
|
||||||
|
public abstract async void notify_dialing();
|
||||||
|
public abstract async void retract_dialing();
|
||||||
public abstract async void notify_subscription_request(Conversation conversation);
|
public abstract async void notify_subscription_request(Conversation conversation);
|
||||||
public abstract async void notify_connection_error(Account account, ConnectionManager.ConnectionError error);
|
public abstract async void notify_connection_error(Account account, ConnectionManager.ConnectionError error);
|
||||||
public abstract async void notify_muc_invite(Account account, Jid room_jid, Jid from_jid, string inviter_display_name);
|
public abstract async void notify_muc_invite(Account account, Jid room_jid, Jid from_jid, string inviter_display_name);
|
||||||
|
|
|
@ -71,6 +71,12 @@ public class Register : StreamInteractionModule, Object{
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async string? change_password(Account account, string new_pw){
|
||||||
|
XmppStream stream = stream_interactor.get_stream(account);
|
||||||
|
if (stream == null) return "Connection unavailable";
|
||||||
|
return yield stream.get_module(Xep.InBandRegistration.Module.IDENTITY).change_password(stream, account.full_jid, new_pw);
|
||||||
|
}
|
||||||
|
|
||||||
public class ServerAvailabilityReturn {
|
public class ServerAvailabilityReturn {
|
||||||
public bool available { get; set; }
|
public bool available { get; set; }
|
||||||
public TlsCertificateFlags? error_flags { get; set; }
|
public TlsCertificateFlags? error_flags { get; set; }
|
||||||
|
@ -229,3 +235,4 @@ public class Register : StreamInteractionModule, Object{
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,25 @@ using Qlite;
|
||||||
namespace Dino {
|
namespace Dino {
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
|
#if _WIN32
|
||||||
|
[CCode (cname = "ShellExecuteA", cheader_filename = "windows.h")]
|
||||||
|
private static extern int ShellExecuteA(int* hwnd, string operation, string file, string parameters, string directory, int showCmd);
|
||||||
|
|
||||||
|
[CCode (cname = "CoInitialize", cheader_filename = "windows.h")]
|
||||||
|
private static extern int CoInitialize(void* reserved);
|
||||||
|
|
||||||
|
[CCode (cname = "CoUninitialize", cheader_filename = "windows.h")]
|
||||||
|
private static extern void CoUninitialize();
|
||||||
|
|
||||||
|
private static int ShellExecute(string operation, string file) {
|
||||||
|
CoInitialize(null);
|
||||||
|
var result = ShellExecuteA(null, operation, file, null, null, 1);
|
||||||
|
CoUninitialize();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public static Message.Type get_message_type_for_conversation(Conversation conversation) {
|
public static Message.Type get_message_type_for_conversation(Conversation conversation) {
|
||||||
switch (conversation.type_) {
|
switch (conversation.type_) {
|
||||||
case Conversation.Type.CHAT:
|
case Conversation.Type.CHAT:
|
||||||
|
@ -29,6 +48,33 @@ public class Util {
|
||||||
assert_not_reached();
|
assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void launch_default_for_uri(string file_uri)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
ShellExecute("open", file_uri);
|
||||||
|
#else
|
||||||
|
AppInfo.launch_default_for_uri(file_uri, null);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string get_content_type(FileInfo fileInfo)
|
||||||
|
{
|
||||||
|
#if _WIN32
|
||||||
|
string fileName = fileInfo.get_name();
|
||||||
|
int fileNameLength = fileName.length;
|
||||||
|
int extIndex = fileName.last_index_of(".");
|
||||||
|
if (extIndex < fileNameLength)
|
||||||
|
{
|
||||||
|
string extension = fileName.substring(extIndex, fileNameLength - extIndex);
|
||||||
|
string mime_type = ContentType.get_mime_type(extension);
|
||||||
|
if (mime_type != null && mime_type.length != 0)
|
||||||
|
{
|
||||||
|
return mime_type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return fileInfo.get_content_type();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ set(RESOURCE_LIST
|
||||||
conversation_content_view/view.ui
|
conversation_content_view/view.ui
|
||||||
manage_accounts/account_row.ui
|
manage_accounts/account_row.ui
|
||||||
manage_accounts/add_account_dialog.ui
|
manage_accounts/add_account_dialog.ui
|
||||||
|
manage_accounts/change_password_dialog.ui
|
||||||
manage_accounts/dialog.ui
|
manage_accounts/dialog.ui
|
||||||
menu_add.ui
|
menu_add.ui
|
||||||
menu_app.ui
|
menu_app.ui
|
||||||
|
@ -203,6 +204,7 @@ SOURCES
|
||||||
|
|
||||||
src/ui/contact_details/settings_provider.vala
|
src/ui/contact_details/settings_provider.vala
|
||||||
src/ui/contact_details/permissions_provider.vala
|
src/ui/contact_details/permissions_provider.vala
|
||||||
|
src/ui/contact_details/history_provider.vala
|
||||||
|
|
||||||
src/ui/conversation_details.vala
|
src/ui/conversation_details.vala
|
||||||
|
|
||||||
|
@ -217,6 +219,7 @@ SOURCES
|
||||||
|
|
||||||
src/ui/manage_accounts/account_row.vala
|
src/ui/manage_accounts/account_row.vala
|
||||||
src/ui/manage_accounts/add_account_dialog.vala
|
src/ui/manage_accounts/add_account_dialog.vala
|
||||||
|
src/ui/manage_accounts/change_password_dialog.vala
|
||||||
src/ui/manage_accounts/dialog.vala
|
src/ui/manage_accounts/dialog.vala
|
||||||
|
|
||||||
src/ui/occupant_menu/list.vala
|
src/ui/occupant_menu/list.vala
|
||||||
|
@ -256,7 +259,13 @@ OPTIONS
|
||||||
)
|
)
|
||||||
|
|
||||||
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DG_LOG_DOMAIN="dino")
|
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\" -DG_LOG_DOMAIN="dino")
|
||||||
|
if(WIN32)
|
||||||
|
add_link_options("-Wl,--export-all-symbols")
|
||||||
|
set(CMAKE_RC_COMPILE_OBJECT "<CMAKE_RC_COMPILER> --use-temp-file -O coff <DEFINES> -i <SOURCE> -o <OBJECT>")
|
||||||
|
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET} dino-info.rc)
|
||||||
|
else(WIN32)
|
||||||
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET})
|
add_executable(dino ${MAIN_VALA_C} ${MAIN_GRESOURCES_TARGET})
|
||||||
|
endif(WIN32)
|
||||||
add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
|
add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
|
||||||
target_include_directories(dino PRIVATE src)
|
target_include_directories(dino PRIVATE src)
|
||||||
target_link_libraries(dino libdino ${MAIN_PACKAGES})
|
target_link_libraries(dino libdino ${MAIN_PACKAGES})
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
<file>manage_accounts/account_row.ui</file>
|
<file>manage_accounts/account_row.ui</file>
|
||||||
<file>manage_accounts/add_account_dialog.ui</file>
|
<file>manage_accounts/add_account_dialog.ui</file>
|
||||||
<file>manage_accounts/dialog.ui</file>
|
<file>manage_accounts/dialog.ui</file>
|
||||||
|
<file>manage_accounts/change_password_dialog.ui</file>
|
||||||
<file>menu_add.ui</file>
|
<file>menu_add.ui</file>
|
||||||
<file>menu_app.ui</file>
|
<file>menu_app.ui</file>
|
||||||
<file>menu_conversation.ui</file>
|
<file>menu_conversation.ui</file>
|
||||||
|
|
158
main/data/manage_accounts/change_password_dialog.ui
Normal file
158
main/data/manage_accounts/change_password_dialog.ui
Normal file
|
@ -0,0 +1,158 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<interface>
|
||||||
|
<requires lib="gtk" version="4.0"/>
|
||||||
|
<template class="DinoUiChangePasswordDialog">
|
||||||
|
<property name="title" translatable="1">Change password</property>
|
||||||
|
<property name="valign">center</property>
|
||||||
|
<property name="modal">True</property>
|
||||||
|
<child internal-child="content_area">
|
||||||
|
<object class="GtkBox">
|
||||||
|
<child>
|
||||||
|
<object class="GtkGrid" id="info_grid">
|
||||||
|
<property name="orientation">vertical</property>
|
||||||
|
<property name="margin-start">20</property>
|
||||||
|
<property name="margin-end">20</property>
|
||||||
|
<property name="margin-top">20</property>
|
||||||
|
<property name="margin-bottom">20</property>
|
||||||
|
<property name="row-spacing">7</property>
|
||||||
|
<property name="column-spacing">10</property>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="1">Current password</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="current_passwd_entry">
|
||||||
|
<property name="activates_default">1</property>
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="width_request">200</property>
|
||||||
|
<property name="visibility">False</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">0</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="1">New password</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="new_passwd_entry">
|
||||||
|
<property name="activates_default">1</property>
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="width_request">200</property>
|
||||||
|
<property name="visibility">False</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel">
|
||||||
|
<property name="label" translatable="1">Confirm new password</property>
|
||||||
|
<property name="xalign">1</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkEntry" id="confirm_new_passwd_entry">
|
||||||
|
<property name="activates_default">1</property>
|
||||||
|
<property name="hexpand">1</property>
|
||||||
|
<property name="width_request">200</property>
|
||||||
|
<property name="visibility">False</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkLabel" id="change_password_error_label">
|
||||||
|
<!-- property name="xalign">0</property -->
|
||||||
|
<property name="halign">center</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="margin-top">7</property>
|
||||||
|
<attributes>
|
||||||
|
<attribute name="scale" value="0.9"></attribute>
|
||||||
|
</attributes>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">3</property>
|
||||||
|
<property name="column-span">2</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="cancel_button">
|
||||||
|
<property name="label" translatable="1">Cancel</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">0</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="change_password_button">
|
||||||
|
<property name="halign">end</property>
|
||||||
|
<property name="hexpand">True</property>
|
||||||
|
<property name="sensitive">0</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">1</property>
|
||||||
|
<property name="row">4</property>
|
||||||
|
</layout>
|
||||||
|
<style>
|
||||||
|
<class name="text-button"/>
|
||||||
|
<class name="suggested-action"/>
|
||||||
|
</style>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStack" id="change_password_stack">
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">label</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkLabel" >
|
||||||
|
<property name="label" translatable="1">Change password</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkStackPage">
|
||||||
|
<property name="name">spinner</property>
|
||||||
|
<property name="child">
|
||||||
|
<object class="GtkSpinner">
|
||||||
|
<property name="spinning">True</property>
|
||||||
|
</object>
|
||||||
|
</property>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<action-widgets>
|
||||||
|
<action-widget response="cancel">cancel_button</action-widget>
|
||||||
|
<action-widget response="ok" default="true">change_password_button</action-widget>
|
||||||
|
</action-widgets>
|
||||||
|
</template>
|
||||||
|
</interface>
|
|
@ -165,7 +165,17 @@
|
||||||
<layout>
|
<layout>
|
||||||
<property name="column">1</property>
|
<property name="column">1</property>
|
||||||
<property name="row">2</property>
|
<property name="row">2</property>
|
||||||
<property name="column-span">2</property>
|
<property name="column-span">1</property>
|
||||||
|
</layout>
|
||||||
|
</object>
|
||||||
|
</child>
|
||||||
|
<child>
|
||||||
|
<object class="GtkButton" id="password_change_btn">
|
||||||
|
<property name="label">⚙️</property>
|
||||||
|
<layout>
|
||||||
|
<property name="column">2</property>
|
||||||
|
<property name="row">2</property>
|
||||||
|
<property name="column-span">1</property>
|
||||||
</layout>
|
</layout>
|
||||||
</object>
|
</object>
|
||||||
</child>
|
</child>
|
||||||
|
|
21
main/dino-info.rc
Normal file
21
main/dino-info.rc
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
1 VERSIONINFO
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "080904E4"
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "Dino"
|
||||||
|
VALUE "FileDescription", "Dino - Modern XMPP (""Jabber"") Chat Client"
|
||||||
|
VALUE "InternalName", "dino"
|
||||||
|
VALUE "LegalCopyright", "Dino"
|
||||||
|
VALUE "OriginalFilename", "dino.exe"
|
||||||
|
VALUE "ProductName", "Dino"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x809, 1252
|
||||||
|
END
|
||||||
|
END
|
||||||
|
|
||||||
|
DINO_ICO ICON "./dino.ico"
|
BIN
main/dino.ico
Normal file
BIN
main/dino.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 98 KiB |
|
@ -39,6 +39,7 @@ sources = files(
|
||||||
'src/ui/chat_input/view.vala',
|
'src/ui/chat_input/view.vala',
|
||||||
'src/ui/contact_details/permissions_provider.vala',
|
'src/ui/contact_details/permissions_provider.vala',
|
||||||
'src/ui/contact_details/settings_provider.vala',
|
'src/ui/contact_details/settings_provider.vala',
|
||||||
|
'src/ui/contact_details/history_provider.vala',
|
||||||
'src/ui/conversation_content_view/call_widget.vala',
|
'src/ui/conversation_content_view/call_widget.vala',
|
||||||
'src/ui/conversation_content_view/chat_state_populator.vala',
|
'src/ui/conversation_content_view/chat_state_populator.vala',
|
||||||
'src/ui/conversation_content_view/content_populator.vala',
|
'src/ui/conversation_content_view/content_populator.vala',
|
||||||
|
@ -71,6 +72,7 @@ sources = files(
|
||||||
'src/ui/main_window_controller.vala',
|
'src/ui/main_window_controller.vala',
|
||||||
'src/ui/manage_accounts/account_row.vala',
|
'src/ui/manage_accounts/account_row.vala',
|
||||||
'src/ui/manage_accounts/add_account_dialog.vala',
|
'src/ui/manage_accounts/add_account_dialog.vala',
|
||||||
|
'src/ui/manage_accounts/change_password_dialog.vala',
|
||||||
'src/ui/manage_accounts/dialog.vala',
|
'src/ui/manage_accounts/dialog.vala',
|
||||||
'src/ui/notifier_freedesktop.vala',
|
'src/ui/notifier_freedesktop.vala',
|
||||||
'src/ui/notifier_gnotifications.vala',
|
'src/ui/notifier_gnotifications.vala',
|
||||||
|
|
|
@ -1176,6 +1176,24 @@ msgstr "لقد أعددت كل شيء!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "أنهي"
|
msgstr "أنهي"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "اضغط هنا لبداية المحادثة أو للإنضمام إلى قناة."
|
#~ msgstr "اضغط هنا لبداية المحادثة أو للإنضمام إلى قناة."
|
||||||
|
|
||||||
|
|
|
@ -1163,6 +1163,24 @@ msgstr "Tot llest!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finalitza"
|
msgstr "Finalitza"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Feu clic aquí per a començar una conversa o unir-vos a un canal."
|
#~ msgstr "Feu clic aquí per a començar una conversa o unir-vos a un canal."
|
||||||
|
|
||||||
|
|
|
@ -1166,5 +1166,22 @@ msgstr "Vše připraveno!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Dokončit"
|
msgstr "Dokončit"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Kliknutím sem zahájíte konverzaci nebo se připojíte ke kanálu."
|
#~ msgstr "Kliknutím sem zahájíte konverzaci nebo se připojíte ke kanálu."
|
||||||
|
|
|
@ -1153,3 +1153,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1161,6 +1161,23 @@ msgstr "Fertig!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Fertig"
|
msgstr "Fertig"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Klicke hier, um eine Unterhaltung zu starten oder einem Kanal beizutreten."
|
#~ "Klicke hier, um eine Unterhaltung zu starten oder einem Kanal beizutreten."
|
||||||
|
|
|
@ -1154,3 +1154,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1169,6 +1169,23 @@ msgstr "Όλα έτοιμα!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Ολοκλήρωση"
|
msgstr "Ολοκλήρωση"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Κάντε κλικ εδώ για να ξεκινήσετε μια συνομιλία ή να εισέλθετε σε ένα "
|
#~ "Κάντε κλικ εδώ για να ξεκινήσετε μια συνομιλία ή να εισέλθετε σε ένα "
|
||||||
|
|
|
@ -1144,3 +1144,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1162,6 +1162,24 @@ msgstr "Ĉio pretas!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Fini"
|
msgstr "Fini"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Alklaku ĉi tie por komenci konversacion aŭ aliĝi al kanalo."
|
#~ msgstr "Alklaku ĉi tie por komenci konversacion aŭ aliĝi al kanalo."
|
||||||
|
|
||||||
|
|
|
@ -1166,6 +1166,23 @@ msgstr "¡Todo listo!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finalizado"
|
msgstr "Finalizado"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Pulsar aquí para iniciar una conversación o unirse a un conversación en "
|
#~ "Pulsar aquí para iniciar una conversación o unirse a un conversación en "
|
||||||
|
|
|
@ -1165,6 +1165,23 @@ msgstr "Guztia ezarri da!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Amaitu"
|
msgstr "Amaitu"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Klikatu hemen elkarrizketa berri bat hasi edo kanal batean sartzeko."
|
#~ "Klikatu hemen elkarrizketa berri bat hasi edo kanal batean sartzeko."
|
||||||
|
|
|
@ -1161,6 +1161,23 @@ msgstr "همه تنظیم شده!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "اتمام"
|
msgstr "اتمام"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "برای شروع گفتگو یا پیوستن به کانال اینجا کلیک کنید."
|
#~ msgstr "برای شروع گفتگو یا پیوستن به کانال اینجا کلیک کنید."
|
||||||
|
|
||||||
|
|
|
@ -1164,6 +1164,23 @@ msgstr ""
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "No active conversations"
|
#~ msgid "No active conversations"
|
||||||
#~ msgstr "Ei aktiivisia keskusteluja"
|
#~ msgstr "Ei aktiivisia keskusteluja"
|
||||||
|
|
||||||
|
|
|
@ -1166,6 +1166,23 @@ msgstr "Tout est prêt !"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Terminer"
|
msgstr "Terminer"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Cliquez ici pour commencer une discussion ou rejoindre un salon."
|
#~ msgstr "Cliquez ici pour commencer une discussion ou rejoindre un salon."
|
||||||
|
|
||||||
|
|
|
@ -1166,6 +1166,23 @@ msgstr "Todo feito!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Rematar"
|
msgstr "Rematar"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Preme aquí para iniciar unha conversa ou unirte a unha canle."
|
#~ msgstr "Preme aquí para iniciar unha conversa ou unirte a unha canle."
|
||||||
|
|
||||||
|
|
|
@ -1169,6 +1169,23 @@ msgstr "Minden készen áll!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Befejezés"
|
msgstr "Befejezés"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Kattintson ide egy beszélgetés indításához vagy egy csatornához való "
|
#~ "Kattintson ide egy beszélgetés indításához vagy egy csatornához való "
|
||||||
|
|
|
@ -1157,5 +1157,22 @@ msgstr "Selesai!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Selesai"
|
msgstr "Selesai"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Klik untuk memulai percakapan atau bergabung dengan channel."
|
#~ msgstr "Klik untuk memulai percakapan atau bergabung dengan channel."
|
||||||
|
|
|
@ -1161,6 +1161,23 @@ msgstr "Omni es pret!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finir"
|
msgstr "Finir"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Fa un clic ti-ci por iniciar un conversation o adherer a un channel."
|
#~ "Fa un clic ti-ci por iniciar un conversation o adherer a un channel."
|
||||||
|
|
|
@ -1161,5 +1161,22 @@ msgstr "Allt klárt!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Loka"
|
msgstr "Loka"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Smelltu hér til að hefja samtal eða taka þátt í rás."
|
#~ msgstr "Smelltu hér til að hefja samtal eða taka þátt í rás."
|
||||||
|
|
|
@ -1165,6 +1165,23 @@ msgstr "Tutto pronto!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Fine"
|
msgstr "Fine"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Fai clic qui per iniziare una conversazione o per entrare in un canale."
|
#~ "Fai clic qui per iniziare una conversazione o per entrare in un canale."
|
||||||
|
|
|
@ -1158,6 +1158,23 @@ msgstr "すべてのセットアップが完了しました!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "完了"
|
msgstr "完了"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "トークを始めたりトークルームに参加したりするには、ここをクリックしてくださ"
|
#~ "トークを始めたりトークルームに参加したりするには、ここをクリックしてくださ"
|
||||||
|
|
|
@ -1153,3 +1153,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1166,5 +1166,22 @@ msgstr "모든 설정이 끝났습니다!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "완료"
|
msgstr "완료"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "대화를 시작하거나 채널에 들어가려면 여기를 누르세요."
|
#~ msgstr "대화를 시작하거나 채널에 들어가려면 여기를 누르세요."
|
||||||
|
|
|
@ -1157,6 +1157,23 @@ msgstr "Alles ageriicht!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Ofschléissen"
|
msgstr "Ofschléissen"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Klick hei fir eng Konversatioun ze starten oder engem Channel "
|
#~ "Klick hei fir eng Konversatioun ze starten oder engem Channel "
|
||||||
|
|
|
@ -1169,6 +1169,23 @@ msgstr "Viskas nustatyta!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Užbaigti"
|
msgstr "Užbaigti"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Spustelėkite čia norėdami pradėti pokalbį ar prisijungti prie kanalo."
|
#~ "Spustelėkite čia norėdami pradėti pokalbį ar prisijungti prie kanalo."
|
||||||
|
|
|
@ -1154,3 +1154,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1167,6 +1167,23 @@ msgstr "Ferdig oppsatt."
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Fullfør"
|
msgstr "Fullfør"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Klikk her for å starte en samtale, eller ta del i en kanal."
|
#~ msgstr "Klikk her for å starte en samtale, eller ta del i en kanal."
|
||||||
|
|
||||||
|
|
|
@ -1163,6 +1163,23 @@ msgstr "Klaar!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Voltooien"
|
msgstr "Voltooien"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Klik hier om een gesprek te starten of deel te nemen aan een kanaal."
|
#~ "Klik hier om een gesprek te starten of deel te nemen aan een kanaal."
|
||||||
|
|
|
@ -1165,6 +1165,23 @@ msgstr "Tot es prèst !"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Terminar"
|
msgstr "Terminar"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Clicatz aquí per començar una conversacion o jónher una sala."
|
#~ msgstr "Clicatz aquí per començar una conversacion o jónher una sala."
|
||||||
|
|
||||||
|
|
|
@ -1169,6 +1169,23 @@ msgstr "Wszystko gotowe!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Zakończ"
|
msgstr "Zakończ"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Kliknij tutaj, aby rozpocząć rozmowę albo dołączyć do kanału."
|
#~ msgstr "Kliknij tutaj, aby rozpocząć rozmowę albo dołączyć do kanału."
|
||||||
|
|
||||||
|
|
|
@ -1163,5 +1163,22 @@ msgstr "Tudo configurado!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finalizado"
|
msgstr "Finalizado"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Clique aqui para iniciar uma conversa or entrar num canal."
|
#~ msgstr "Clique aqui para iniciar uma conversa or entrar num canal."
|
||||||
|
|
|
@ -1164,6 +1164,23 @@ msgstr "Tudo configurado!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finalizado"
|
msgstr "Finalizado"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Clique aqui para inicial uma conversa ou entrar em um canal."
|
#~ msgstr "Clique aqui para inicial uma conversa ou entrar em um canal."
|
||||||
|
|
||||||
|
|
|
@ -1170,6 +1170,23 @@ msgstr "Gata!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Finalizare"
|
msgstr "Finalizare"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr ""
|
#~ msgstr ""
|
||||||
#~ "Apăsați aici pentru a porni o conversație sau a vă alătura unui canal."
|
#~ "Apăsați aici pentru a porni o conversație sau a vă alătura unui canal."
|
||||||
|
|
|
@ -1167,6 +1167,23 @@ msgstr "Всё готово!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Закончить"
|
msgstr "Закончить"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr "Изменить пароль"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr "Текущий пароль"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr "Новый пароль"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr "Подтверждение пароля"
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Нажмите здесь, чтобы начать беседу или присоединиться к каналу."
|
#~ msgstr "Нажмите здесь, чтобы начать беседу или присоединиться к каналу."
|
||||||
|
|
||||||
|
|
|
@ -1163,5 +1163,22 @@ msgstr "Gjithçka e ujdisur!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Përfundoje"
|
msgstr "Përfundoje"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Klikoni këtu që të nisni një bisedë ose të hyni në një kanal."
|
#~ msgstr "Klikoni këtu që të nisni një bisedë ose të hyni në një kanal."
|
||||||
|
|
|
@ -1163,6 +1163,23 @@ msgstr "Färdigt!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Slutför"
|
msgstr "Slutför"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Klicka här för att starta en konversation eller gå med i en kanal."
|
#~ msgstr "Klicka här för att starta en konversation eller gå med i en kanal."
|
||||||
|
|
||||||
|
|
|
@ -1153,3 +1153,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1162,6 +1162,23 @@ msgstr "Hepsi tamam!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "Bitir"
|
msgstr "Bitir"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "Bir sohbet başlatmak ya da kanala katılmak için buraya tıkla."
|
#~ msgstr "Bir sohbet başlatmak ya da kanala katılmak için buraya tıkla."
|
||||||
|
|
||||||
|
|
|
@ -1158,3 +1158,20 @@ msgstr ""
|
||||||
#: main/data/manage_accounts/add_account_dialog.ui:506
|
#: main/data/manage_accounts/add_account_dialog.ui:506
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1155,6 +1155,23 @@ msgstr "都准备好了!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "完成"
|
msgstr "完成"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "点击此处以开始对话或加入频道。"
|
#~ msgstr "点击此处以开始对话或加入频道。"
|
||||||
|
|
||||||
|
|
|
@ -1154,6 +1154,23 @@ msgstr "全部設定好了!"
|
||||||
msgid "Finish"
|
msgid "Finish"
|
||||||
msgstr "完成"
|
msgstr "完成"
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :5
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :103
|
||||||
|
msgid "Change password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :21
|
||||||
|
msgid "Current password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :43
|
||||||
|
msgid "New password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: main/src/ui/manage_accounts/change_password_dialog.vala :65
|
||||||
|
msgid "Confirm new password"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#~ msgid "Click here to start a conversation or join a channel."
|
#~ msgid "Click here to start a conversation or join a channel."
|
||||||
#~ msgstr "點擊此處開始對話或加入聊天室。"
|
#~ msgstr "點擊此處開始對話或加入聊天室。"
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,12 @@ namespace Dino {
|
||||||
void main(string[] args) {
|
void main(string[] args) {
|
||||||
|
|
||||||
try{
|
try{
|
||||||
|
#if _WIN32
|
||||||
|
var pangocairoResult = Environment.set_variable("PANGOCAIRO_BACKEND", "fontconfig", false);
|
||||||
|
if (!pangocairoResult) {
|
||||||
|
warning("Unable to set PANGOCAIRO_BACKEND environment variable to fontconfig");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
string? exec_path = args.length > 0 ? args[0] : null;
|
string? exec_path = args.length > 0 ? args[0] : null;
|
||||||
SearchPathGenerator search_path_generator = new SearchPathGenerator(exec_path);
|
SearchPathGenerator search_path_generator = new SearchPathGenerator(exec_path);
|
||||||
Intl.textdomain(GETTEXT_PACKAGE);
|
Intl.textdomain(GETTEXT_PACKAGE);
|
||||||
|
|
52
main/src/ui/contact_details/history_provider.vala
Normal file
52
main/src/ui/contact_details/history_provider.vala
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
using Gee;
|
||||||
|
using Gtk;
|
||||||
|
|
||||||
|
using Dino.Entities;
|
||||||
|
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
|
namespace Dino.Ui.ContactDetails {
|
||||||
|
|
||||||
|
public class HistoryProvider : Plugins.ContactDetailsProvider, Object {
|
||||||
|
public string id { get { return "history_settings"; } }
|
||||||
|
|
||||||
|
private StreamInteractor stream_interactor;
|
||||||
|
|
||||||
|
private HashMap<Account, HashMap<Jid, Cancellable>> sync_cancellables = new HashMap<Account, HashMap<Jid, Cancellable>>(Account.hash_func, Account.equals_func);
|
||||||
|
|
||||||
|
public HistoryProvider(StreamInteractor stream_interactor) {
|
||||||
|
this.stream_interactor = stream_interactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void populate(Conversation conversation, Plugins.ContactDetails contact_details, Plugins.WidgetType type) {
|
||||||
|
if (type != Plugins.WidgetType.GTK4) return;
|
||||||
|
|
||||||
|
EntityInfo entity_info = stream_interactor.get_module(EntityInfo.IDENTITY);
|
||||||
|
|
||||||
|
string RESYNC_LABEL = _("Resync");
|
||||||
|
string RESYNC_DESC_LABEL = _("Fetch a complete MAM history for this chat");
|
||||||
|
entity_info.has_feature.begin(conversation.account, conversation.counterpart, Xmpp.MessageArchiveManagement.NS_URI, (_, res) => {
|
||||||
|
bool can_do_mam = entity_info.has_feature.end(res);
|
||||||
|
if (can_do_mam) {
|
||||||
|
Button resync_button = new Button.with_label(RESYNC_LABEL);
|
||||||
|
contact_details.add("Permissions", RESYNC_DESC_LABEL, "", resync_button);
|
||||||
|
resync_button.clicked.connect(() => {
|
||||||
|
if (!sync_cancellables.has_key(conversation.account)) {
|
||||||
|
sync_cancellables[conversation.account] = new HashMap<Jid, Cancellable>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sync_cancellables[conversation.account].has_key(conversation.counterpart.bare_jid)) {
|
||||||
|
sync_cancellables[conversation.account][conversation.counterpart.bare_jid] = new Cancellable();
|
||||||
|
var history_sync = stream_interactor.get_module(MessageProcessor.IDENTITY).history_sync;
|
||||||
|
history_sync.fetch_history.begin(conversation.account, conversation.counterpart.bare_jid, sync_cancellables[conversation.account][conversation.counterpart.bare_jid], (_, res) => {
|
||||||
|
history_sync.fetch_everything.end(res);
|
||||||
|
sync_cancellables[conversation.account].unset(conversation.counterpart.bare_jid);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -176,7 +176,7 @@ public class FileWidgetController : Object {
|
||||||
|
|
||||||
private void open_file() {
|
private void open_file() {
|
||||||
try{
|
try{
|
||||||
AppInfo.launch_default_for_uri(file_transfer.get_file().get_uri(), null);
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -242,7 +242,15 @@ public class MessageMetaItem : ContentMetaItem {
|
||||||
|
|
||||||
public static bool on_label_activate_link(string uri) {
|
public static bool on_label_activate_link(string uri) {
|
||||||
// Always handle xmpp URIs with Dino
|
// Always handle xmpp URIs with Dino
|
||||||
if (!uri.has_prefix("xmpp:")) return false;
|
if (!uri.has_prefix("xmpp:")) {
|
||||||
|
#if _WIN32
|
||||||
|
Dino.Util.launch_default_for_uri(uri);
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
File file = File.new_for_uri(uri);
|
File file = File.new_for_uri(uri);
|
||||||
Dino.Application.get_default().open(new File[]{file}, "");
|
Dino.Application.get_default().open(new File[]{file}, "");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -152,6 +152,7 @@ namespace Dino.Ui.ConversationDetails {
|
||||||
Application app = GLib.Application.get_default() as Application;
|
Application app = GLib.Application.get_default() as Application;
|
||||||
app.plugin_registry.register_contact_details_entry(new ContactDetails.SettingsProvider(stream_interactor));
|
app.plugin_registry.register_contact_details_entry(new ContactDetails.SettingsProvider(stream_interactor));
|
||||||
app.plugin_registry.register_contact_details_entry(new ContactDetails.PermissionsProvider(stream_interactor));
|
app.plugin_registry.register_contact_details_entry(new ContactDetails.PermissionsProvider(stream_interactor));
|
||||||
|
app.plugin_registry.register_contact_details_entry(new ContactDetails.HistoryProvider(stream_interactor));
|
||||||
|
|
||||||
foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) {
|
foreach (Plugins.ContactDetailsProvider provider in app.plugin_registry.contact_details_entries) {
|
||||||
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4);
|
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4);
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class FileSendOverlay {
|
||||||
|
|
||||||
private async void load_file_widget(File file, FileInfo file_info) {
|
private async void load_file_widget(File file, FileInfo file_info) {
|
||||||
string file_name = file_info.get_display_name();
|
string file_name = file_info.get_display_name();
|
||||||
string mime_type = file_info.get_content_type();
|
string mime_type = Dino.Util.get_content_type(file_info);
|
||||||
|
|
||||||
bool is_image = false;
|
bool is_image = false;
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ public class AddAccountDialog : Gtk.Dialog {
|
||||||
// Button is opening a registration website
|
// Button is opening a registration website
|
||||||
if (form.oob != null) {
|
if (form.oob != null) {
|
||||||
try {
|
try {
|
||||||
AppInfo.launch_default_for_uri(form.oob, null);
|
Dino.Util.launch_default_for_uri(form.oob);
|
||||||
} catch (Error e) { }
|
} catch (Error e) { }
|
||||||
show_sign_in_jid();
|
show_sign_in_jid();
|
||||||
return;
|
return;
|
||||||
|
|
100
main/src/ui/manage_accounts/change_password_dialog.vala
Normal file
100
main/src/ui/manage_accounts/change_password_dialog.vala
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
using Gee;
|
||||||
|
using Gtk;
|
||||||
|
//using Pango;
|
||||||
|
|
||||||
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
|
namespace Dino.Ui{
|
||||||
|
|
||||||
|
[GtkTemplate (ui = "/im/dino/Dino/manage_accounts/change_password_dialog.ui")]
|
||||||
|
public class ChangePasswordDialog : Gtk.Dialog {
|
||||||
|
|
||||||
|
[GtkChild] private unowned Button change_password_button;
|
||||||
|
[GtkChild] private unowned Stack change_password_stack;
|
||||||
|
[GtkChild] private unowned Button cancel_button;
|
||||||
|
[GtkChild] private unowned Entry current_passwd_entry;
|
||||||
|
[GtkChild] private unowned Entry new_passwd_entry;
|
||||||
|
[GtkChild] private unowned Entry confirm_new_passwd_entry;
|
||||||
|
[GtkChild] private unowned Label change_password_error_label;
|
||||||
|
|
||||||
|
private bool are_forms_empty;
|
||||||
|
private Account account;
|
||||||
|
private StreamInteractor stream_interactor;
|
||||||
|
|
||||||
|
public ChangePasswordDialog(Account a, StreamInteractor s){
|
||||||
|
Object(use_header_bar : 1);
|
||||||
|
this.stream_interactor = s;
|
||||||
|
this.account = a;
|
||||||
|
Util.force_error_color(change_password_error_label);
|
||||||
|
cancel_button.clicked.connect(() => { close(); });
|
||||||
|
current_passwd_entry.changed.connect(on_current_passwd_entry_changed);
|
||||||
|
new_passwd_entry.changed.connect(on_new_passwd_entry_changed);
|
||||||
|
confirm_new_passwd_entry.changed.connect(on_confirm_new_passwd_entry_changed);
|
||||||
|
change_password_button.clicked.connect(on_change_password_button_clicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void are_psswd_nonempty(){
|
||||||
|
EntryBuffer newpsswd = new_passwd_entry.get_buffer();
|
||||||
|
EntryBuffer confirm_newpsswd = confirm_new_passwd_entry.get_buffer();
|
||||||
|
|
||||||
|
if (current_passwd_entry.get_text_length() > 0
|
||||||
|
&& new_passwd_entry.get_text_length() > 0
|
||||||
|
&& confirm_new_passwd_entry.get_text_length() > 0
|
||||||
|
&& newpsswd.get_text() == confirm_newpsswd.get_text()){
|
||||||
|
are_forms_empty = false;
|
||||||
|
change_password_button.sensitive = true;
|
||||||
|
} else {
|
||||||
|
are_forms_empty = true;
|
||||||
|
change_password_button.sensitive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void check_new_passwd(){
|
||||||
|
EntryBuffer newpsswd = new_passwd_entry.get_buffer();
|
||||||
|
EntryBuffer confirm_newpsswd = confirm_new_passwd_entry.get_buffer();
|
||||||
|
|
||||||
|
if (newpsswd.get_text() != confirm_newpsswd.get_text()){
|
||||||
|
new_passwd_entry.add_css_class("error");
|
||||||
|
confirm_new_passwd_entry.add_css_class("error");
|
||||||
|
} else {
|
||||||
|
new_passwd_entry.remove_css_class("error");
|
||||||
|
confirm_new_passwd_entry.remove_css_class("error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void on_current_passwd_entry_changed(){
|
||||||
|
are_psswd_nonempty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void on_new_passwd_entry_changed(){
|
||||||
|
are_psswd_nonempty();
|
||||||
|
check_new_passwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void on_confirm_new_passwd_entry_changed(){
|
||||||
|
are_psswd_nonempty();
|
||||||
|
check_new_passwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async void on_change_password_button_clicked(){
|
||||||
|
string? pw_input = current_passwd_entry.get_buffer().get_text();
|
||||||
|
string? new_pw_input = new_passwd_entry.get_buffer().get_text();
|
||||||
|
|
||||||
|
if (pw_input != null && account.password == pw_input){
|
||||||
|
change_password_button.sensitive = false;
|
||||||
|
change_password_stack.visible_child_name = "spinner";
|
||||||
|
string ret = yield stream_interactor.get_module(Register.IDENTITY).change_password(account, new_pw_input);
|
||||||
|
change_password_button.sensitive = true;
|
||||||
|
change_password_stack.visible_child_name = "label";
|
||||||
|
if (ret == null)
|
||||||
|
close();
|
||||||
|
|
||||||
|
change_password_error_label.label = ret;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
change_password_error_label.label = _("Wrong password");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ public class Dialog : Gtk.Dialog {
|
||||||
[GtkChild] public unowned Label state_label;
|
[GtkChild] public unowned Label state_label;
|
||||||
[GtkChild] public unowned Switch active_switch;
|
[GtkChild] public unowned Switch active_switch;
|
||||||
[GtkChild] public unowned Util.EntryLabelHybrid password_hybrid;
|
[GtkChild] public unowned Util.EntryLabelHybrid password_hybrid;
|
||||||
|
[GtkChild] public unowned Button password_change_btn;
|
||||||
[GtkChild] public unowned Util.EntryLabelHybrid alias_hybrid;
|
[GtkChild] public unowned Util.EntryLabelHybrid alias_hybrid;
|
||||||
[GtkChild] public unowned Grid settings_list;
|
[GtkChild] public unowned Grid settings_list;
|
||||||
|
|
||||||
|
@ -44,10 +45,12 @@ 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(() => { selected_account.password = password_hybrid.text; });
|
password_hybrid.entry.changed.connect(() => { selected_account.password = password_hybrid.text; });
|
||||||
|
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();
|
||||||
label_hybrid_group.add(alias_hybrid);
|
label_hybrid_group.add(alias_hybrid);
|
||||||
label_hybrid_group.add(password_hybrid);
|
label_hybrid_group.add(password_hybrid);
|
||||||
|
password_change_btn.sensitive = false;
|
||||||
|
|
||||||
main_stack.set_visible_child_name("no_accounts");
|
main_stack.set_visible_child_name("no_accounts");
|
||||||
|
|
||||||
|
@ -109,6 +112,12 @@ public class Dialog : Gtk.Dialog {
|
||||||
add_account_dialog.present();
|
add_account_dialog.present();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void show_change_psswd_dialog() {
|
||||||
|
ChangePasswordDialog change_psswd_dialog = new ChangePasswordDialog(selected_account, stream_interactor);
|
||||||
|
change_psswd_dialog.set_transient_for(this);
|
||||||
|
change_psswd_dialog.present();
|
||||||
|
}
|
||||||
|
//
|
||||||
private void remove_account(AccountRow account_item) {
|
private void remove_account(AccountRow account_item) {
|
||||||
Gtk.MessageDialog msg = new Gtk.MessageDialog (
|
Gtk.MessageDialog msg = new Gtk.MessageDialog (
|
||||||
this, Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
|
this, Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
|
||||||
|
@ -215,8 +224,10 @@ public class Dialog : Gtk.Dialog {
|
||||||
case ConnectionManager.ConnectionState.CONNECTING:
|
case ConnectionManager.ConnectionState.CONNECTING:
|
||||||
state_label.label = _("Connecting…"); break;
|
state_label.label = _("Connecting…"); break;
|
||||||
case ConnectionManager.ConnectionState.CONNECTED:
|
case ConnectionManager.ConnectionState.CONNECTED:
|
||||||
|
password_change_btn.sensitive = true;
|
||||||
state_label.label = _("Connected"); break;
|
state_label.label = _("Connected"); break;
|
||||||
case ConnectionManager.ConnectionState.DISCONNECTED:
|
case ConnectionManager.ConnectionState.DISCONNECTED:
|
||||||
|
password_change_btn.sensitive = false;
|
||||||
state_label.label = _("Disconnected"); break;
|
state_label.label = _("Disconnected"); break;
|
||||||
}
|
}
|
||||||
state_label.remove_css_class("is_error");
|
state_label.remove_css_class("is_error");
|
||||||
|
@ -224,6 +235,7 @@ public class Dialog : Gtk.Dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
private string get_connection_error_description(ConnectionManager.ConnectionError error) {
|
private string get_connection_error_description(ConnectionManager.ConnectionError error) {
|
||||||
|
password_change_btn.sensitive = false;
|
||||||
switch (error.source) {
|
switch (error.source) {
|
||||||
case ConnectionManager.ConnectionError.Source.SASL:
|
case ConnectionManager.ConnectionError.Source.SASL:
|
||||||
return _("Wrong password");
|
return _("Wrong password");
|
||||||
|
|
|
@ -118,7 +118,6 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
|
||||||
|
|
||||||
HashTable<string, Variant> hash_table = new HashTable<string, Variant>(null, null);
|
HashTable<string, Variant> hash_table = new HashTable<string, Variant>(null, null);
|
||||||
hash_table["image-path"] = "call-start-symbolic";
|
hash_table["image-path"] = "call-start-symbolic";
|
||||||
hash_table["sound-name"] = new Variant.string("phone-incoming-call");
|
|
||||||
hash_table["urgency"] = new Variant.byte(2);
|
hash_table["urgency"] = new Variant.byte(2);
|
||||||
hash_table["desktop-entry"] = new Variant.string(Dino.Application.get_default().get_application_id());
|
hash_table["desktop-entry"] = new Variant.string(Dino.Application.get_default().get_application_id());
|
||||||
hash_table["category"] = new Variant.string("im");
|
hash_table["category"] = new Variant.string("im");
|
||||||
|
@ -153,6 +152,9 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
|
||||||
} catch (Error e) { }
|
} catch (Error e) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void notify_dialing(){}
|
||||||
|
public async void retract_dialing(){}
|
||||||
|
|
||||||
public async void notify_subscription_request(Conversation conversation) {
|
public async void notify_subscription_request(Conversation conversation) {
|
||||||
string summary = _("Subscription request");
|
string summary = _("Subscription request");
|
||||||
string body = Markup.escape_text(conversation.counterpart.to_string());
|
string body = Markup.escape_text(conversation.counterpart.to_string());
|
||||||
|
|
|
@ -87,6 +87,9 @@ namespace Dino.Ui {
|
||||||
GLib.Application.get_default().withdraw_notification(call.id.to_string());
|
GLib.Application.get_default().withdraw_notification(call.id.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async void notify_dialing(){}
|
||||||
|
public async void retract_dialing(){}
|
||||||
|
|
||||||
public async void notify_subscription_request(Conversation conversation) {
|
public async void notify_subscription_request(Conversation conversation) {
|
||||||
Notification notification = new Notification(_("Subscription request"));
|
Notification notification = new Notification(_("Subscription request"));
|
||||||
notification.set_body(conversation.counterpart.to_string());
|
notification.set_body(conversation.counterpart.to_string());
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
if(WIN32)
|
||||||
|
add_link_options("-Wl,--export-all-symbols")
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
foreach(plugin ${PLUGINS})
|
foreach(plugin ${PLUGINS})
|
||||||
add_subdirectory(${plugin})
|
add_subdirectory(${plugin})
|
||||||
endforeach(plugin)
|
endforeach(plugin)
|
||||||
|
|
|
@ -177,6 +177,13 @@ private static uint8[] get_uint8_from_data(Data data) {
|
||||||
|
|
||||||
private static void initialize() {
|
private static void initialize() {
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
|
#if _WIN32
|
||||||
|
string gpg = GLib.Environment.find_program_in_path("gpg.exe");
|
||||||
|
if (gpg != null && gpg.length > 0)
|
||||||
|
{
|
||||||
|
set_global_flag("w32-inst-dir", GLib.Path.get_dirname(gpg));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
check_version();
|
check_version();
|
||||||
initialized = true;
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -665,6 +665,9 @@ namespace GPG {
|
||||||
[CCode (cname = "gpgme_strerror")]
|
[CCode (cname = "gpgme_strerror")]
|
||||||
public unowned string strerror(GPGError.Error err);
|
public unowned string strerror(GPGError.Error err);
|
||||||
|
|
||||||
|
[CCode (cname = "gpgme_set_global_flag")]
|
||||||
|
public int set_global_flag(string name, string value);
|
||||||
|
|
||||||
private void throw_if_error(GPGError.Error error) throws GLib.Error {
|
private void throw_if_error(GPGError.Error error) throws GLib.Error {
|
||||||
if (error.code != GPGError.ErrorCode.NO_ERROR) {
|
if (error.code != GPGError.ErrorCode.NO_ERROR) {
|
||||||
throw new GLib.Error(-1, error.code, "%s", error.to_string());
|
throw new GLib.Error(-1, error.code, "%s", error.to_string());
|
||||||
|
|
28
plugins/phone-ringer/CMakeLists.txt
Normal file
28
plugins/phone-ringer/CMakeLists.txt
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
find_packages(PHONE_RINGER_PACKAGES REQUIRED
|
||||||
|
Canberra
|
||||||
|
Gee
|
||||||
|
GLib
|
||||||
|
GModule
|
||||||
|
GObject
|
||||||
|
GDKPixbuf2
|
||||||
|
)
|
||||||
|
|
||||||
|
vala_precompile(PHONE_RINGER_VALA_C
|
||||||
|
SOURCES
|
||||||
|
src/plugin.vala
|
||||||
|
src/register_plugin.vala
|
||||||
|
CUSTOM_VAPIS
|
||||||
|
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/dino.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/qlite.vapi
|
||||||
|
PACKAGES
|
||||||
|
${PHONE_RINGER_PACKAGES}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(${VALA_CFLAGS})
|
||||||
|
add_library(phone-ringer SHARED ${PHONE_RINGER_VALA_C})
|
||||||
|
target_link_libraries(phone-ringer libdino ${PHONE_RINGER_PACKAGES})
|
||||||
|
set_target_properties(phone-ringer PROPERTIES PREFIX "")
|
||||||
|
set_target_properties(phone-ringer PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/)
|
||||||
|
|
||||||
|
install(TARGETS phone-ringer ${PLUGIN_INSTALL})
|
90
plugins/phone-ringer/src/plugin.vala
Normal file
90
plugins/phone-ringer/src/plugin.vala
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
using Dino.Entities;
|
||||||
|
using Xmpp;
|
||||||
|
|
||||||
|
namespace Dino.Plugins.PhoneRinger {
|
||||||
|
|
||||||
|
public class Plugin : RootInterface, NotificationProvider, Object {
|
||||||
|
|
||||||
|
private const int GAP = 1;
|
||||||
|
private const int RINGER_ID = 0;
|
||||||
|
private const int DIALER_ID = 1;
|
||||||
|
private Canberra.Context sound_context;
|
||||||
|
private Canberra.Proplist ringer_props;
|
||||||
|
private Canberra.Proplist dialer_props;
|
||||||
|
private bool ringing = false;
|
||||||
|
private bool dialing = false;
|
||||||
|
|
||||||
|
private void loop_ringer() {
|
||||||
|
sound_context.play_full(RINGER_ID, ringer_props, (c, id, code) => {
|
||||||
|
if (code == Canberra.Error.CANCELED) return;
|
||||||
|
Timeout.add_seconds(GAP, () => {
|
||||||
|
if (!ringing) return Source.REMOVE;
|
||||||
|
loop_ringer();
|
||||||
|
return Source.REMOVE;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loop_dialer() {
|
||||||
|
sound_context.play_full(DIALER_ID, dialer_props, (c, id, code) => {
|
||||||
|
if (code == Canberra.Error.CANCELED) return;
|
||||||
|
Timeout.add_seconds(GAP, () => {
|
||||||
|
if (!dialing) return Source.REMOVE;
|
||||||
|
loop_dialer();
|
||||||
|
return Source.REMOVE;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registered(Dino.Application app) {
|
||||||
|
|
||||||
|
Canberra.Context.create(out sound_context);
|
||||||
|
Canberra.Proplist.create(out ringer_props);
|
||||||
|
Canberra.Proplist.create(out dialer_props);
|
||||||
|
ringer_props.sets(Canberra.PROP_EVENT_ID, "phone-incoming-call");
|
||||||
|
ringer_props.sets(Canberra.PROP_EVENT_DESCRIPTION, "Incoming call");
|
||||||
|
dialer_props.sets(Canberra.PROP_EVENT_ID, "phone-outgoing-calling");
|
||||||
|
dialer_props.sets(Canberra.PROP_EVENT_DESCRIPTION, "Outgoing call");
|
||||||
|
|
||||||
|
NotificationEvents notification_events = app.stream_interactor.get_module(NotificationEvents.IDENTITY);
|
||||||
|
notification_events.register_notification_provider.begin(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() { }
|
||||||
|
|
||||||
|
public async void notify_call(Call call, Conversation conversation, bool video, bool multiparty, string conversation_display_name){
|
||||||
|
ringing = true;
|
||||||
|
loop_ringer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void retract_call_notification(Call call, Conversation conversation){
|
||||||
|
ringing = false;
|
||||||
|
sound_context.cancel(RINGER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void notify_dialing(){
|
||||||
|
dialing = true;
|
||||||
|
loop_dialer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void retract_dialing(){
|
||||||
|
dialing = false;
|
||||||
|
sound_context.cancel(DIALER_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double get_priority(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void notify_message(Message message, Conversation conversation, string conversation_display_name, string? participant_display_name){}
|
||||||
|
public async void notify_file(FileTransfer file_transfer, Conversation conversation, bool is_image, string conversation_display_name, string? participant_display_name){}
|
||||||
|
public async void notify_subscription_request(Conversation conversation){}
|
||||||
|
public async void notify_connection_error(Account account, ConnectionManager.ConnectionError error){}
|
||||||
|
public async void notify_muc_invite(Account account, Jid room_jid, Jid from_jid, string inviter_display_name){}
|
||||||
|
public async void notify_voice_request(Conversation conversation, Jid from_jid){}
|
||||||
|
public async void retract_content_item_notifications(){}
|
||||||
|
public async void retract_conversation_notifications(Conversation conversation){}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
plugins/phone-ringer/src/register_plugin.vala
Normal file
3
plugins/phone-ringer/src/register_plugin.vala
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
public Type register_plugin(Module module) {
|
||||||
|
return typeof (Dino.Plugins.PhoneRinger.Plugin);
|
||||||
|
}
|
|
@ -49,6 +49,8 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
device_monitor.get_bus().add_watch(Priority.DEFAULT, on_device_monitor_message);
|
device_monitor.get_bus().add_watch(Priority.DEFAULT, on_device_monitor_message);
|
||||||
device_monitor.start();
|
device_monitor.start();
|
||||||
foreach (Gst.Device device in device_monitor.get_devices()) {
|
foreach (Gst.Device device in device_monitor.get_devices()) {
|
||||||
|
if (device.properties == null) continue;
|
||||||
|
if (device.properties.get_string("device.api") == "wasapi") continue;
|
||||||
if (device.properties.has_name("pipewire-proplist") && device.has_classes("Audio")) continue;
|
if (device.properties.has_name("pipewire-proplist") && device.has_classes("Audio")) continue;
|
||||||
if (device.properties.get_string("device.class") == "monitor") continue;
|
if (device.properties.get_string("device.class") == "monitor") continue;
|
||||||
if (devices.any_match((it) => it.matches(device))) continue;
|
if (devices.any_match((it) => it.matches(device))) continue;
|
||||||
|
@ -276,7 +278,6 @@ public class Dino.Plugins.Rtp.Plugin : RootInterface, VideoCallPlugin, Object {
|
||||||
device_monitor.stop();
|
device_monitor.stop();
|
||||||
}
|
}
|
||||||
destroy_call_pipe();
|
destroy_call_pipe();
|
||||||
Gst.deinit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool supports(string? media) {
|
public bool supports(string? media) {
|
||||||
|
|
43
plugins/win32-fonts/CMakeLists.txt
Normal file
43
plugins/win32-fonts/CMakeLists.txt
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
find_packages(WIN32_FONTS_PACKAGES REQUIRED
|
||||||
|
Gee
|
||||||
|
GLib
|
||||||
|
GModule
|
||||||
|
GObject
|
||||||
|
GTK4
|
||||||
|
)
|
||||||
|
|
||||||
|
set(RESOURCE_LIST
|
||||||
|
larger.css
|
||||||
|
)
|
||||||
|
|
||||||
|
compile_gresources(
|
||||||
|
WIN32_FONTS_GRESOURCES_TARGET
|
||||||
|
WIN32_FONTS_GRESOURCES_XML
|
||||||
|
TARGET ${CMAKE_CURRENT_BINARY_DIR}/resources/resources.c
|
||||||
|
TYPE EMBED_C
|
||||||
|
RESOURCES ${RESOURCE_LIST}
|
||||||
|
PREFIX /im/dino/Dino/win32-fonts
|
||||||
|
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data
|
||||||
|
)
|
||||||
|
|
||||||
|
vala_precompile(WIN32_FONTS_VALA_C
|
||||||
|
SOURCES
|
||||||
|
src/plugin.vala
|
||||||
|
src/register_plugin.vala
|
||||||
|
CUSTOM_VAPIS
|
||||||
|
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/dino.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/qlite.vapi
|
||||||
|
PACKAGES
|
||||||
|
${WIN32_FONTS_PACKAGES}
|
||||||
|
GRESOURCES
|
||||||
|
${WIN32_FONTS_GRESOURCES_XML}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(${VALA_CFLAGS})
|
||||||
|
add_library(win32-fonts SHARED ${WIN32_FONTS_VALA_C} ${WIN32_FONTS_GRESOURCES_TARGET})
|
||||||
|
target_link_libraries(win32-fonts libdino ${WIN32_FONTS_PACKAGES})
|
||||||
|
set_target_properties(win32-fonts PROPERTIES PREFIX "")
|
||||||
|
set_target_properties(win32-fonts PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/)
|
||||||
|
|
||||||
|
install(TARGETS win32-fonts ${PLUGIN_INSTALL})
|
3
plugins/win32-fonts/data/larger.css
Normal file
3
plugins/win32-fonts/data/larger.css
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
* {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
}
|
16
plugins/win32-fonts/src/plugin.vala
Normal file
16
plugins/win32-fonts/src/plugin.vala
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
using Gtk;
|
||||||
|
|
||||||
|
namespace Dino.Plugins.Win32Fonts {
|
||||||
|
|
||||||
|
public class Plugin : RootInterface, Object {
|
||||||
|
|
||||||
|
public void registered(Dino.Application app) {
|
||||||
|
CssProvider larger_fonts = new CssProvider();
|
||||||
|
larger_fonts.load_from_resource("/im/dino/Dino/win32-fonts/larger.css");
|
||||||
|
StyleContext.add_provider_for_display(Gdk.Display.get_default(), larger_fonts, STYLE_PROVIDER_PRIORITY_APPLICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void shutdown() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
3
plugins/win32-fonts/src/register_plugin.vala
Normal file
3
plugins/win32-fonts/src/register_plugin.vala
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
public Type register_plugin(Module module) {
|
||||||
|
return typeof (Dino.Plugins.Win32Fonts.Plugin);
|
||||||
|
}
|
1
plugins/windows-notification/.gitignore
vendored
Normal file
1
plugins/windows-notification/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/yolort
|
77
plugins/windows-notification/CMakeLists.txt
Normal file
77
plugins/windows-notification/CMakeLists.txt
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
set(GETTEXT_PACKAGE "dino-windows-notifications")
|
||||||
|
find_package(Gettext)
|
||||||
|
include(${GETTEXT_USE_FILE})
|
||||||
|
gettext_compile(${GETTEXT_PACKAGE} SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../main/po TARGET_NAME ${GETTEXT_PACKAGE}-translations)
|
||||||
|
|
||||||
|
project(windows-notification)
|
||||||
|
|
||||||
|
find_packages(WINDOWS_NOTIFICATION_PACKAGES REQUIRED
|
||||||
|
Gee
|
||||||
|
GLib
|
||||||
|
GModule
|
||||||
|
GObject
|
||||||
|
GTK4
|
||||||
|
)
|
||||||
|
|
||||||
|
vala_precompile(WINDOWS_NOTIFICATION_VALA_C
|
||||||
|
SOURCES
|
||||||
|
src/windows_notifications_plugin.vala
|
||||||
|
src/windows_notifications_register_plugin.vala
|
||||||
|
src/toast_notification_builder.vala
|
||||||
|
src/win_notification_provider.vala
|
||||||
|
CUSTOM_VAPIS
|
||||||
|
${CMAKE_BINARY_DIR}/exports/xmpp-vala.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/dino.vapi
|
||||||
|
${CMAKE_BINARY_DIR}/exports/qlite.vapi
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vapi/win32.vapi
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vapi/winrt.vapi
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vapi/shortcutcreator.vapi
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vapi/enums.vapi
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/vapi/winrt_windows_ui_notifications.vapi
|
||||||
|
PACKAGES
|
||||||
|
${WINDOWS_NOTIFICATION_PACKAGES}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(WINDOWS_API_SOURCES
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-enums.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-event-token.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-toast-notification.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt-toast-notifier.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/gobject/winrt.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/win32.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/converter.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/dyn_mod.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/ginvoke.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/api/src/shortcutcreator.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_definitions(${VALA_CFLAGS} -DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\" -DLOCALE_INSTALL_DIR=\"${LOCALE_INSTALL_DIR}\")
|
||||||
|
add_library(windows-notification SHARED ${WINDOWS_NOTIFICATION_VALA_C} ${WINDOWS_API_SOURCES})
|
||||||
|
add_dependencies(windows-notification ${GETTEXT_PACKAGE}-translations)
|
||||||
|
|
||||||
|
target_include_directories(windows-notification
|
||||||
|
PRIVATE
|
||||||
|
${PROJECT_SOURCE_DIR}/api/include
|
||||||
|
${PROJECT_SOURCE_DIR}/api/include/gobject
|
||||||
|
${PROJECT_SOURCE_DIR}/yolort/include
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(shlwapi_LIBRARY shlwapi libshlwapi libshlwapi.a HINTS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
||||||
|
if(NOT shlwapi_LIBRARY)
|
||||||
|
message(FATAL_ERROR "shlwapi library not found")
|
||||||
|
endif(NOT shlwapi_LIBRARY)
|
||||||
|
|
||||||
|
find_library(ntdll_LIBRARY ntdll libntdll libntdll.a HINTS ${CMAKE_C_IMPLICIT_LINK_DIRECTORIES})
|
||||||
|
if(NOT ntdll_LIBRARY)
|
||||||
|
message(FATAL_ERROR "ntdll library not found")
|
||||||
|
endif(NOT ntdll_LIBRARY)
|
||||||
|
|
||||||
|
target_link_libraries(windows-notification libdino ${shlwapi_LIBRARY} ${ntdll_LIBRARY} ${WINDOWS_NOTIFICATION_PACKAGES})
|
||||||
|
target_compile_features(windows-notification PRIVATE cxx_std_17)
|
||||||
|
target_compile_definitions(windows-notification PRIVATE WINRT_GLIB_H_INSIDE)
|
||||||
|
target_compile_options(windows-notification PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-iquote ${PROJECT_SOURCE_DIR}/yolort/include/winrt/yolort_impl>)
|
||||||
|
|
||||||
|
set_target_properties(windows-notification PROPERTIES PREFIX "")
|
||||||
|
set_target_properties(windows-notification PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/plugins/)
|
||||||
|
|
||||||
|
install(TARGETS windows-notification ${PLUGIN_INSTALL})
|
10
plugins/windows-notification/README.md
Normal file
10
plugins/windows-notification/README.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# Windows Notification plugin for Dino
|
||||||
|
Plugin that allows native notifications on Dino on both Windows 8.1 and Windows 10.
|
||||||
|
Currently supports:
|
||||||
|
* Actionable notification (with action button on Windows 10)
|
||||||
|
* Shows avatar image
|
||||||
|
|
||||||
|
# Special thanks
|
||||||
|
- GObject wrapper based on https://github.com/endlessm/xapian-glib/
|
||||||
|
- YoloRT which allows compilation on GCC https://github.com/Yuubi-san/YoloRT
|
||||||
|
- Notification builder inspired by https://gitlab.gnome.org/Philipp/glib/-/commits/windows_toast_notification_backend
|
8
plugins/windows-notification/api/include/converter.hpp
Normal file
8
plugins/windows-notification/api/include/converter.hpp
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
std::wstring sview_to_wstr(const std::string_view str);
|
||||||
|
gchar* wsview_to_char(const std::wstring_view wstr);
|
29
plugins/windows-notification/api/include/dyn_mod.hpp
Normal file
29
plugins/windows-notification/api/include/dyn_mod.hpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
|
||||||
|
#ifndef DYN_MOD_HPP
|
||||||
|
#define DYN_MOD_HPP
|
||||||
|
|
||||||
|
namespace dyn_mod
|
||||||
|
{
|
||||||
|
using punny_func = void();
|
||||||
|
|
||||||
|
punny_func &load_symbol(
|
||||||
|
const wchar_t *mod_path,
|
||||||
|
const char *mod_dbgnym,
|
||||||
|
const char *symbol);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
inline T &load_symbol(
|
||||||
|
const wchar_t *const mod_path, const char *const mod_dbgnym,
|
||||||
|
const char *const symbol)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<T &>(load_symbol(mod_path, mod_dbgnym, symbol));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define dyn_load_symbol_ns(mod_name, namespace, symbol) \
|
||||||
|
::dyn_mod::load_symbol<decltype(namespace::symbol)>( \
|
||||||
|
L ## mod_name, mod_name, #symbol)
|
||||||
|
|
||||||
|
#define dyn_load_symbol(mod_name, symbol) dyn_load_symbol_ns(mod_name, ,symbol)
|
||||||
|
|
||||||
|
#endif
|
172
plugins/windows-notification/api/include/ginvoke.hpp
Normal file
172
plugins/windows-notification/api/include/ginvoke.hpp
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
|
||||||
|
#ifndef GINVOKE_HPP
|
||||||
|
#define GINVOKE_HPP
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <utility>
|
||||||
|
#include <optional>
|
||||||
|
#include <variant>
|
||||||
|
#include <iterator>
|
||||||
|
#include <functional>
|
||||||
|
#include <exception>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cinttypes>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "overload.hpp"
|
||||||
|
#include "make_array.hpp"
|
||||||
|
#include "hexify.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace glib {
|
||||||
|
|
||||||
|
namespace impl
|
||||||
|
{
|
||||||
|
using static_c_str = const char *;
|
||||||
|
using varstring_t = std::variant<std::string, static_c_str>;
|
||||||
|
struct varstring : varstring_t
|
||||||
|
{
|
||||||
|
varstring(std::string &&s) noexcept : varstring_t{std::move(s)} {}
|
||||||
|
varstring(static_c_str &&s) noexcept : varstring_t{std::move(s)} {}
|
||||||
|
varstring(std::nullptr_t) = delete;
|
||||||
|
varstring(const varstring &) = delete;
|
||||||
|
varstring(varstring &&) = default;
|
||||||
|
|
||||||
|
const char* c_str() const && = delete;
|
||||||
|
const char* c_str() const &
|
||||||
|
{
|
||||||
|
return std::visit(overload{
|
||||||
|
[](const std::string &s){ return s.c_str(); },
|
||||||
|
[](const static_c_str s){ return s; }
|
||||||
|
}, static_cast<const varstring_t &>(*this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct hresult
|
||||||
|
{
|
||||||
|
std::int32_t code;
|
||||||
|
varstring message;
|
||||||
|
};
|
||||||
|
std::optional<hresult> get_if_hresult_error(std::exception_ptr) noexcept;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OStream, typename T,
|
||||||
|
std::enable_if_t<!std::is_enum_v<T>,int> = 0>
|
||||||
|
inline auto &describe_argument(OStream &s, const T &a)
|
||||||
|
{ return s << a; }
|
||||||
|
template<typename OStream, typename T,
|
||||||
|
std::enable_if_t< std::is_enum_v<T>,int> = 0>
|
||||||
|
inline auto &describe_argument(OStream &s, const T &a)
|
||||||
|
{ return s << static_cast<std::underlying_type_t<T>>(a); }
|
||||||
|
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, std::string_view const a)
|
||||||
|
{ return s << std::quoted(a); }
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, const std::string & a)
|
||||||
|
{ return s << std::quoted(a); }
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, const char * const a)
|
||||||
|
{ return s << std::quoted(a); }
|
||||||
|
// TODO: overload for const GString *
|
||||||
|
|
||||||
|
// not implemented (TODO maybe):
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, std::wstring_view const a) = delete;
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, const std::wstring & a) = delete;
|
||||||
|
template<typename OStream>
|
||||||
|
inline auto &describe_argument(OStream &s, const wchar_t * const a) = delete;
|
||||||
|
|
||||||
|
inline impl::varstring describe_arguments() noexcept { return {""}; }
|
||||||
|
|
||||||
|
template<typename... Arg>
|
||||||
|
inline impl::varstring describe_arguments(const Arg &... a) noexcept try
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
((describe_argument(ss,a) << ','), ...);
|
||||||
|
auto s = std::move(ss).str();
|
||||||
|
s.pop_back();
|
||||||
|
return {std::move(s)};
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
return {"<failed to stringify arguments>"};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define FORMAT "%s(%s) failed: %s"
|
||||||
|
template<typename... Arg>
|
||||||
|
inline void log_invocation_failure(const char *e,
|
||||||
|
const char *func_name, const Arg &... a) noexcept
|
||||||
|
{
|
||||||
|
const auto args = describe_arguments(a...);
|
||||||
|
g_warning(FORMAT, func_name, args.c_str(), e);
|
||||||
|
}
|
||||||
|
template<typename... Arg>
|
||||||
|
inline void log_invocation_failure_desc(const char *e, const char *e_desc,
|
||||||
|
const char *func_name, const Arg &... a) noexcept
|
||||||
|
{
|
||||||
|
const auto args = describe_arguments(a...);
|
||||||
|
g_warning(FORMAT": %s", func_name, args.c_str(), e, e_desc);
|
||||||
|
}
|
||||||
|
#undef FORMAT
|
||||||
|
|
||||||
|
struct regular_void {};
|
||||||
|
|
||||||
|
template<typename Invokable, typename... Arg>
|
||||||
|
inline auto invoke(Invokable &&i, const Arg &... a)
|
||||||
|
{
|
||||||
|
using R = decltype(std::invoke(std::forward<Invokable>(i), a...));
|
||||||
|
if constexpr (std::is_void_v<R>)
|
||||||
|
{
|
||||||
|
std::invoke(std::forward<Invokable>(i), a...);
|
||||||
|
return regular_void{};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return std::invoke(std::forward<Invokable>(i), a...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Invokable, typename... Arg>
|
||||||
|
inline auto try_invoke(
|
||||||
|
const char *func_name, Invokable &&i, const Arg &... a) noexcept
|
||||||
|
-> std::optional<decltype(invoke(std::forward<Invokable>(i), a...))>
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return invoke(std::forward<Invokable>(i), a...);
|
||||||
|
}
|
||||||
|
catch (const std::exception &e)
|
||||||
|
{
|
||||||
|
log_invocation_failure(e.what(), func_name, a...);
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
if (const auto e = impl::get_if_hresult_error(std::current_exception()))
|
||||||
|
{
|
||||||
|
auto hr = make_array("hresult 0x01234567\0");
|
||||||
|
hexify32(static_cast<std::uint32_t>(e->code), std::end(hr)-1);
|
||||||
|
log_invocation_failure_desc(
|
||||||
|
std::begin(hr), e->message.c_str(), func_name, a...);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
log_invocation_failure("unknown error", func_name, a...);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace glib
|
||||||
|
|
||||||
|
|
||||||
|
#define g_try_invoke(invokable, ...) \
|
||||||
|
glib::try_invoke(#invokable, invokable, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define g_try_invoke0(invokable) \
|
||||||
|
glib::try_invoke(#invokable, invokable)
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef __WINRT_ENUMS_H__
|
||||||
|
#define __WINRT_ENUMS_H__
|
||||||
|
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON \
|
||||||
|
(winrtWindowsUINotificationsToastDismissalReason_get_type())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* winrt_Windows_UI_Notifications_Toast_Dismissal_Reason:
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_Activated: Notification was activated, clicked or through
|
||||||
|
* a button
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_ApplicationHidden: Application was hidden
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_TimedOut: Notification timed out
|
||||||
|
*
|
||||||
|
* Reasons for a notification dismissal
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_Activated,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_ApplicationHidden,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_DISMISSAL_REASON_TimedOut,
|
||||||
|
} winrtWindowsUINotificationsToastDismissalReason;
|
||||||
|
|
||||||
|
GType winrt_windows_ui_notifications_toast_dismissal_reason_get_type();
|
||||||
|
|
||||||
|
#define WINRT_TYPE_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE \
|
||||||
|
(winrt_windows_ui_notifications_toast_template_type_get_type())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* winrtWindowsUINotificationsToastTemplateType:
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText01
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText02
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText03
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText04
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText01
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText02
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText03
|
||||||
|
* @WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText04
|
||||||
|
*
|
||||||
|
* Basic templates for a toast notification.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText01,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText02,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText03,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastImageAndText04,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText01,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText02,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText03,
|
||||||
|
WINRT_WINDOWS_UI_NOTIFICATIONS_TOAST_TEMPLATE_TYPE_ToastText04,
|
||||||
|
} winrtWindowsUINotificationsToastTemplateType;
|
||||||
|
|
||||||
|
GType winrt_windows_ui_notifications_toast_template_type_get_type();
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __WINRT_ENUMS_H__ */
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef __WINRT_GLIB_EVENTTOKEN_PRIVATE_H__
|
||||||
|
#define __WINRT_GLIB_EVENTTOKEN_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include "winrt-headers.h"
|
||||||
|
|
||||||
|
#include "winrt-event-token.h"
|
||||||
|
|
||||||
|
winrtEventToken* winrt_event_token_new_from_token(winrt::event_token* token);
|
||||||
|
winrt::event_token* winrt_event_token_get_internal(winrtEventToken* self);
|
||||||
|
|
||||||
|
#endif /* __WINRT_GLIB_EVENTTOKEN_PRIVATE_H__ */
|
|
@ -0,0 +1,36 @@
|
||||||
|
#ifndef __WINRT_GLIB_EVENTTOKEN_H__
|
||||||
|
#define __WINRT_GLIB_EVENTTOKEN_H__
|
||||||
|
|
||||||
|
#if !defined(WINRT_GLIB_H_INSIDE) && !defined(WINRT_GLIB_COMPILATION)
|
||||||
|
#error "Only <winrt-glib.h> can be included directly."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "winrt-glib-types.h"
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define WINRT_TYPE_EVENT_TOKEN (winrt_event_token_get_type())
|
||||||
|
|
||||||
|
G_DECLARE_DERIVABLE_TYPE (winrtEventToken, winrt_event_token, WINRT, EVENT_TOKEN, GObject)
|
||||||
|
|
||||||
|
struct _winrtEventTokenClass
|
||||||
|
{
|
||||||
|
/*< private >*/
|
||||||
|
GObjectClass parent_class;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gint64 winrt_event_token_get_value(winrtEventToken* self);
|
||||||
|
gboolean winrt_event_token_operator_bool(winrtEventToken* self);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __WINRT_GLIB_EVENTTOKEN_H__ */
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef __WINRT_GLIB_TYPES_H__
|
||||||
|
#define __WINRT_GLIB_TYPES_H__
|
||||||
|
|
||||||
|
#include <gio/gio.h>
|
||||||
|
#include "winrt-enums.h"
|
||||||
|
|
||||||
|
#endif /* __WINRT_GLIB_TYPES_H__ */
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __WINRT_GLIB_H__
|
||||||
|
#define __WINRT_GLIB_H__
|
||||||
|
|
||||||
|
#ifndef WINRT_GLIB_H_INSIDE
|
||||||
|
#define WINRT_GLIB_H_INSIDE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "winrt-enums.h"
|
||||||
|
#include "winrt-glib-types.h"
|
||||||
|
|
||||||
|
#include "winrt.h"
|
||||||
|
#include "winrt-toast-notification.h"
|
||||||
|
#include "winrt-event-token.h"
|
||||||
|
#include "winrt-toast-notifier.h"
|
||||||
|
|
||||||
|
#undef WINRT_GLIB_H_INSIDE
|
||||||
|
|
||||||
|
#endif /* __`WINRT_GLIB_H__ */
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef __WINRT_HEADERS_H__
|
||||||
|
#define __WINRT_HEADERS_H__
|
||||||
|
|
||||||
|
#include <winrt/Windows.UI.Notifications.h>
|
||||||
|
#include <winrt/Windows.Data.Xml.Dom.h>
|
||||||
|
#include <winrt/Windows.Foundation.h>
|
||||||
|
#include <winrt/Windows.Foundation.Collections.h>
|
||||||
|
|
||||||
|
#endif /* __WINRT_HEADERS_H__ */
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __WINRT_GLIB_H_PRIVATE__
|
||||||
|
#define __WINRT_GLIB_H_PRIVATE__
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include "winrt.h"
|
||||||
|
#include "gobject/winrt-headers.h"
|
||||||
|
|
||||||
|
#endif // __WINRT_GLIB_H_PRIVATE__
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue