Compare commits

...

191 commits

Author SHA1 Message Date
egorovnikita d42ea75978 remove unnecessary cloning 2024-03-15 19:37:04 +03:00
egorovnikita ecda670d1e add shared modules to use libcanberra in Flatpak 2024-03-15 19:37:04 +03:00
Maxim Logaev 2587a7e6a9 Merge remote-tracking branch 'kkonsw/resync' into master-windows-changes-test 2024-03-12 18:51:50 +03:00
Maxim Logaev f1aed531e2 Merge remote-tracking branch 'smalishevskiy/test' into master-windows-changes-test 2024-03-12 18:34:26 +03:00
Maxim Logaev 75092caced
Added CI for MSYS2 (MINGW64) (#2)
- Use quotes in windows build script;
- Added missing gstreamer, webrtc-audio-processing and git;
- Added CI for Windows.
---------
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-12 20:01:36 +03:00
Psayker ca1f97e243 Move download yolort headers logic into prepare stage, delete yolort download script 2024-03-12 16:20:13 +03:00
Konstantin Kuznetsov ecb3fb0056 Fetch MAM history for conversations without local mam catchup data 2024-03-12 16:17:39 +03:00
Konstantin Kuznetsov 1a9c55ecc9 Add button to fetch MAM history for conversation 2024-03-12 12:49:07 +03:00
emil 735e6f544a Add gap to ringing and dialing sounds 2024-03-12 11:33:04 +03:00
emil a3958949f0 Phone ringing and dialing 2024-03-12 11:33:04 +03:00
emil 734e1503c7 Remove Gst.deinit (proactive bug fix)
Gst.deinit caused the Dino proces to linger in the background when I
tried using Gst in the phone ringer plugin. My reasoning for leaving it
out even though Gst is not in use anymore in the ringer plugin is that
this is a nasty bug that might crop up again in the future when someone
tries to do anything else at all with Gst.

I did the following things:

- checked this https://gstreamer.freedesktop.org/documentation/gstreamer/gst.html#gst_deinit
- tested that Dino works without the Gst.deinit
- tried looking for a specific reason for the deinit with git log -L 276,+10 -- plugins/rtp/src/plugin.vala

I didn't find anything so this made me conclude that it is better to
leave it out.
2024-03-12 11:33:03 +03:00
Konstantin Kuznetsov bf07ecddb3 Add button to fetch MAM history for conversation 2024-03-12 11:30:39 +03:00
Stanislav Malishevskiy 1a73e9d53d Fix issue #261. 2024-03-12 10:43:40 +03:00
Miquel Lionel fc8fdc166b wip, fixes https://github.com/dino/dino/issues/261
- server refuses to responds in any way to the sent iq stanza
	  and i don't know why, when i send it with the xml console in
	  gajim it works well
2024-03-12 10:43:40 +03:00
Maxim Logaev 9c15a81b40 Fixed build dependencies
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-11 17:10:07 +03:00
Maxim Logaev 3848cf3129 Added build-installer target to build-win64.sh
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-06 23:01:49 +03:00
Maxim Logaev 43502806bc Removed unnecessary installer files
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-06 21:19:13 +03:00
Maxim Logaev b886e2a2f2 Fixed dist-install dir
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-06 21:11:15 +03:00
Maxim Logaev 4674e90d16 Added basic support for NSIS installer
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-06 20:42:19 +03:00
Maxim Logaev a3171e12df Added README-WIN64.md
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-05 23:13:25 +03:00
Maxim Logaev 5f500b4d42 Added build script for windows
Signed-off-by: Maxim Logaev <maxlogaev@proton.me>
2024-03-05 22:58:00 +03:00
Maxim Logaev f9fd66dba5 Merge branch 'origin/master' into master-windows-changes 2024-03-05 15:07:52 +03:00
LAGonauta 1c156e8c9f Fix GPGME 2023-10-09 10:54:55 -04:00
LAGonauta f6fe383ce8 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-10-09 10:54:15 -04:00
LAGonauta 49f331627d Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-07-17 17:28:47 -04:00
LAGonauta 7603990740 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-04-24 19:01:02 -03:00
LAGonauta 7872d21f03 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-04-21 20:43:40 -03:00
LAGonauta 86182a7db9 Check YoloRT checksum before building 2023-02-12 11:17:57 -03:00
LAGonauta 82e6937f21 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-02-12 10:59:16 -03:00
LAGonauta 3d61f175a6 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-01-30 08:53:45 -03:00
LAGonauta 471f8c5f4a Merge remote-tracking branch 'upstream/master' into master-windows-changes 2023-01-08 15:41:07 -03:00
LAGonauta fb05c83c8e Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-12-28 09:13:59 -03:00
LAGonauta ef41c27cb2 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-10-15 13:00:56 -03:00
LAGonauta e638ef0694 Fixed using GTK3 instead of GTK4 2022-08-25 09:29:47 -03:00
LAGonauta a7f7a6d388 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-08-25 08:54:04 -03:00
LAGonauta d507808e40 Automatically set PANGOCAIRO_BACKEND to fontconfig on win32 2022-06-17 18:37:49 -03:00
LAGonauta 2d82a4c195 Removed version from Dino executable
We need a better way to get the version number
2022-06-17 18:37:34 -03:00
LAGonauta c29032bcc6 :Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-06-05 11:12:23 -03:00
LAGonauta 90bd9df891 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-02-25 07:02:20 -03:00
LAGonauta d10badd690 Ignore wasapi devices as they do not work well yet 2022-02-25 07:02:06 -03:00
LAGonauta 11828cc2cf no need to ignore wasapi 2022-02-09 21:09:44 -03:00
LAGonauta a583a44994 fix call notifications buttons not working 2022-02-09 21:01:26 -03:00
LAGonauta dd71e943c3 Merge remote-tracking branch 'upstream/master' into master-windows-changes 2022-02-08 20:32:22 -03:00
LAGonauta b8b74817f7 Merge remote-tracking branch 'upstream/master' into master-windows-changes
# Conflicts:
#	main/src/ui/conversation_content_view/file_widget.vala
#	plugins/CMakeLists.txt
#	plugins/rtp/src/device.vala
#	plugins/rtp/src/plugin.vala
2022-02-08 18:33:09 -03:00
mjk 43fd04ce41 define _POSIX_C_SOURCE=1 on windows
Fixes "undefined reference to `localtime_r`" in, e.g., Vala's GLib.Time.local
when building on mingw-w64.
2022-02-08 18:09:49 -03:00
Felipe 733d612b18
Merge pull request #5 from danielreuther/master-windows-changes-gcc11-fix
Fix compilation on GCC 11
2022-02-08 18:04:58 -03:00
Daniel Reuther 5a335f89d3 Fix compilation on gcc 11 2021-10-23 02:45:52 +02:00
LAGonauta c57fc768aa Do not generate WinRT headers, just download them on build 2021-06-19 11:43:12 -03:00
LAGonauta 88a376c1c2 Build YoloRT on project build 2021-06-19 08:13:39 -03:00
LAGonauta 97753bd5c4 Remove YoloRT from tree 2021-06-19 06:58:40 -03:00
LAGonauta d7118c1b93 Allow devices with properties and use has_classes 2021-06-18 07:46:39 -03:00
LAGonauta 96fbbdd8bb Use correct generic type for ArrayList
Nullable crashes Dino
2021-06-10 20:03:30 -03:00
LAGonauta 4b0c3b8ef0 Add initial call notifications 2021-06-09 07:20:56 -03:00
LAGonauta ee11a2dbcf Do not allow selection of WASAPI devices
Dino would have to resample it own audio, do more book keeping and
somehow find out manually which is the default device.
2021-06-09 07:20:45 -03:00
LAGonauta 064541dd2b Prefer primary DirectSound device on Windows
It automatically selects the default device for use,
there is no book keeping necessary and things just work

The primary DirectSound device has a (NULL) guid, making
it wasy to be found.
2021-06-09 07:20:33 -03:00
LAGonauta 854818133e DelegateToUi must be an owned function 2021-06-09 07:20:14 -03:00
LAGonauta 878bf9ac43 Allow null header, body, applogo, and image on notification builder 2021-06-09 07:20:14 -03:00
LAGonauta e6a521ada9 Add support for inline images to notification 2021-06-09 07:20:14 -03:00
LAGonauta 359dcbf70c Add support for adaptive Windows 10 notifications 2021-06-09 07:20:14 -03:00
mjk c40775b7da comment out unused arguments [-Wunused-parameter] 2021-06-09 07:20:13 -03:00
mjk 934b492357 init Callback completely always
The `token` pointer was left dangerously uninitialized after construction.
2021-06-09 07:20:12 -03:00
mjk 0258980977 replace lists with vectors 2021-06-09 07:20:12 -03:00
mjk 8034a6f344 remove the no-longer-needed -municode compile option 2021-06-09 07:20:10 -03:00
mjk c89671af04 log SetCurrentProcessExplicitAppUserModelID errors 2021-06-09 07:20:10 -03:00
mjk 822b91f40c stop checking for empty AUMIDs
The downstream code handles them just fine.
2021-06-09 07:20:09 -03:00
mjk 332216e63c reflow/respace 2021-06-09 07:20:09 -03:00
mjk 7b6f3ea9f6 replace C-style concurrent initialization of statics
C++ statics are thread-safe as is and are usually implemented more
efficiently. Besides, `volatile` is likely misused here anyway.
2021-06-09 07:20:04 -03:00
mjk 8988b77d57 don't use FALSE as a null pointer constant 2021-06-09 07:20:03 -03:00
mjk 987eb672d5 fix / work around uninitialized fields warnings 2021-06-09 07:20:03 -03:00
mjk 1698d15f7d silence enum stringification warnings by first casting to underlying types 2021-06-09 07:20:02 -03:00
mjk 17c1172d84 work around a (pedantic) format specifier warning 2021-06-09 07:20:02 -03:00
mjk 8f8dfa2e70 move module loading functions out of shortcutcreator.cpp 2021-06-09 07:20:02 -03:00
mjk e8d84d2eda handle empty menu-relative shortcut paths 2021-06-09 07:20:01 -03:00
mjk f1bcb6604f rewrite InitApartment and protect callers from (the rest of the) exceptions
Initializing COM by calling `winrt::init_apartment()` would always cause
stack unwinding *in practice*, which is suboptimal at best, and even using
`apartment_type::single_threaded` still would require exception filtering
*just in case*.
2021-06-09 07:20:01 -03:00
mjk c855d5e7cb protect GetTemplateContent callers from exceptions 2021-06-09 07:20:00 -03:00
mjk ed7c23c8d2 generalize glib::try_invoke to any return-by-value type and void 2021-06-09 07:19:59 -03:00
mjk b1cb64d716 add nullary version of g_try_invoke macro 2021-06-09 07:19:58 -03:00
mjk da424fb73b fiddle with punctuation 2021-06-09 07:19:58 -03:00
mjk 39b51b2d4c make glib::impl::varstring less explosive 2021-06-09 07:19:57 -03:00
mjk 7cb6b3f4b3 fix UB in glib::describe_arguments called with no arguments
Makes failure logging of nullary invokables non-crashy.
2021-06-09 07:19:56 -03:00
mjk 15abe70fc6 handle theoretical future failures of wsview_to_char 2021-06-09 07:19:56 -03:00
mjk ab6ce05aec handle empty hresult_error message specially 2021-06-09 07:19:55 -03:00
mjk c44b1daaf7 make meta-error messages more precise 2021-06-09 07:19:54 -03:00
mjk 5e50d1d2d7 remove an unused include 2021-06-09 07:19:53 -03:00
mjk d3214188d5 use lower-case 0x prefix for hresult code formatting everywhere 2021-06-09 07:19:51 -03:00
mjk 229ff697c4 move some whitespace around 2021-06-09 07:19:50 -03:00
mjk c3624f8490 handle exe paths longer than 259 chars 2021-06-09 07:19:48 -03:00
mjk 597061aed1 work around GetEnvironmentVariable not resetting last error 2021-06-09 07:19:48 -03:00
mjk fd035084de unimplement accidentally implemented wide string overloads of describe_argument 2021-06-09 07:19:47 -03:00
LAGonauta 426f997f9b Fix notifications not hiding 2021-06-09 07:19:47 -03:00
LAGonauta c60e0a828f Add README.md to Windows notification plugin 2021-06-09 07:19:46 -03:00
LAGonauta cc0e206c27 Removed unused library on linker
It is loaded dynamically
2021-06-09 07:19:45 -03:00
LAGonauta 60791cb3f0 Add ginvoke to CMakeLists 2021-06-09 07:19:45 -03:00
mjk f9a3b28624 switch to runtime loading of PropVariantToStringAlloc
Now it really should work.
2021-06-09 07:19:44 -03:00
mjk cb3c6874bc add restoration of shortcut's target path 2021-06-09 07:19:44 -03:00
mjk eeda464ca9 rewrite shortcut management code with RAII, error logging and exceptions
It actually works now.
2021-06-09 07:19:43 -03:00
mjk f193948f4e constify all the things 2021-06-09 07:19:43 -03:00
mjk 401c4a1bb1 change some local functions' signatures 2021-06-09 07:19:43 -03:00
mjk 34519e96bd make GetEnv more robust and not limit length of variables 2021-06-09 07:19:42 -03:00
mjk fb754b0d43 generalize GetShortcutPath into GetEnv 2021-06-09 07:19:42 -03:00
mjk 2eb1eea06e clarify GetCurrentModulePath's name 2021-06-09 07:19:41 -03:00
mjk 5b40d166d2 make GetCurrentModulePath and GetShortcutPath throw win32 errors 2021-06-09 07:19:41 -03:00
mjk 2ad659f777 clarify some entry points' names 2021-06-09 07:19:40 -03:00
mjk b21066c89e mark exception-safe C entry points as such 2021-06-09 07:19:40 -03:00
mjk 1bd1376cea stop exceptions from crossing ABI boundary in a few places 2021-06-09 07:19:40 -03:00
mjk f1b5633ce6 introduce try_invoke -- a logging exception catcher 2021-06-09 07:19:39 -03:00
LAGonauta 3d9dcbcf87 Valac think that getters are always owned by the struct 2021-06-09 07:19:38 -03:00
LAGonauta 8856fcbceb Use g_new0 and g_free to generate raw strings 2021-06-09 07:19:37 -03:00
LAGonauta 94944a9e2a Use async 2021-06-09 07:19:37 -03:00
LAGonauta 7de1c01fe8 Add comment to builder 2021-06-09 07:19:36 -03:00
LAGonauta 0f555da7a9 Fixed crash with multiple notifications
Sometimes an invalid function pointer was called with an invalid context
2021-06-09 07:19:35 -03:00
LAGonauta f2c689fa12 Delegate activate_action to UI thread 2021-06-09 07:19:34 -03:00
LAGonauta 839d2a5316 Initial notification provider using WinRT
Crashes when activating actions, might be related to threads.
2021-06-09 07:19:32 -03:00
LAGonauta be0e1841b8 Anitial builder 2021-06-09 07:19:32 -03:00
LAGonauta 2476b5e04b Initial experiments with notification XML building 2021-06-09 07:19:32 -03:00
LAGonauta bc9b9b95e0 Add template getter 2021-06-09 07:19:31 -03:00
LAGonauta 9d9b9e8e42 Rename plugin vala file 2021-06-09 07:19:31 -03:00
LAGonauta 0153953b5d Rename enums to better match what Vala expects 2021-06-09 07:19:30 -03:00
LAGonauta 363b200272 Add template type enum 2021-06-09 07:19:28 -03:00
LAGonauta c6a96fc025 Cleanup dismissed actions on toast notification finalizer 2021-06-09 07:19:27 -03:00
LAGonauta 898470ed23 Add failed and dimissed actions 2021-06-09 07:19:25 -03:00
LAGonauta 6cdaad315a Fields must be created in the private struct
Also change unordered_map to list, we do not need hashing and stuff.
2021-06-09 07:19:24 -03:00
LAGonauta 91d61843f2 No need to enable coroutines 2021-06-09 07:19:22 -03:00
LAGonauta c4f526329d Remove unity compilation unit 2021-06-09 07:19:21 -03:00
LAGonauta 40bf3d2fd4 Actions can stack 2021-06-09 07:19:20 -03:00
LAGonauta 7fd918f32d Fix string conversion 2021-06-09 07:19:19 -03:00
LAGonauta 1d1b00222f Add toastnotifier 2021-06-09 07:19:17 -03:00
LAGonauta 8df226ec29 Increase ref on event token 2021-06-09 07:19:15 -03:00
LAGonauta 13e0a5c0c4 Use string_view 2021-06-09 07:19:14 -03:00
LAGonauta ca0cab0e36 Initial code to allow buttons and text 2021-06-09 07:19:13 -03:00
LAGonauta ae9671716f Initial GObject wrapper for WinRT notifications
Still missing a lot of stuff
2021-06-09 07:19:11 -03:00
LAGonauta ce0deed0dc Initial callback support 2021-06-09 07:19:09 -03:00
LAGonauta 95051d304a Initial code for using winrt headers 2021-06-09 07:19:08 -03:00
LAGonauta 915dd4c738 Add MIT licensed winrt headers 2021-06-09 07:19:06 -03:00
LAGonauta e3356bb3aa Do not use GLib to open links in messages
Use ShellExecute
2021-06-09 07:19:05 -03:00
LAGonauta 03774a3756 Fix muc invite and voide request not working 2021-06-09 07:19:05 -03:00
LAGonauta 2d63c8ae77 Rename field 2021-06-09 07:19:04 -03:00
LAGonauta 96f96ead7e Use list with all notifications 2021-06-09 07:19:04 -03:00
LAGonauta 5f2e636868 Add notification retraction 2021-06-09 07:19:03 -03:00
LAGonauta d8bb9897a4 Add support for custom actions on notification 2021-06-09 07:19:02 -03:00
LAGonauta 08f2391acc Initial plugin using new notification provider 2021-06-09 07:19:02 -03:00
LAGonauta eae628758c Use VAPI and generate template in-app 2021-06-09 07:19:01 -03:00
LAGonauta 931f09504d Added 32-bit wintoast linker library 2021-06-09 07:19:01 -03:00
LAGonauta 5702b323c9 Use dynamic linking instead of runtime loading
Also made me notice that the signature of the function with the callback was wrong. Oops.
2021-06-09 07:19:00 -03:00
LAGonauta 198bce4a84 Allow null image_path 2021-06-09 07:18:59 -03:00
LAGonauta 8553a7cd86 Add callback support 2021-06-09 07:18:59 -03:00
LAGonauta 642ed6ab1b Convert C code to Vala 2021-06-09 07:18:58 -03:00
LAGonauta d36de2b9ea Use code from Dino.Ui.Util 2021-06-09 07:18:56 -03:00
LAGonauta 49978edebf Clean up 2021-06-09 07:18:55 -03:00
LAGonauta 65a26bce53 Refactor windows-notification plugin 2021-06-09 07:18:53 -03:00
LAGonauta 1d4bb774a5 Initial notification support 2021-06-09 07:18:51 -03:00
LAGonauta 3dd19fad71 Use last_index_of instead of index_of 2021-06-09 07:18:47 -03:00
LAGonauta 4a3306b479 Allow 32-bit linking
Win32 apis are __stdcall
2021-06-09 07:18:45 -03:00
LAGonauta 0b9bebd97e Use Dino.Util.get_content_type also on preview 2021-06-09 07:18:45 -03:00
LAGonauta 24890ca38a Export all plugin symbols on Windows 2021-06-09 07:18:44 -03:00
LAGonauta 50b2a0dc0a Do not hardcode GPG path on Windows 2021-06-09 07:18:43 -03:00
LAGonauta a6515ed826 Add implicit link directories to package HINT path on MingW
Instead of blacklisting those libraries
2021-06-09 07:18:43 -03:00
LAGonauta e7fd7f4726 Add --export-all-symbols to Windows compilation 2021-06-09 07:18:42 -03:00
LAGonauta 9022ac596b Every call to CoInitialize() must be balanced
with a call to CoUninitialize()
2021-06-09 07:18:42 -03:00
LAGonauta 823df3ed70 Add WIN32 fonts as a plugin 2021-06-09 07:18:26 -03:00
LAGonauta 6d5ee03e9e Set Windows executable version from PROJECT_VERSION 2021-06-09 07:17:22 -03:00
LAGonauta 1673ec3481 Added information and Dino icon to Windows executable 2021-06-09 07:17:22 -03:00
LAGonauta 16d0cc6fd9 Set alternate file stream for downloaded files. 2021-06-09 07:17:21 -03:00
LAGonauta 03f17b8f39 Fixed some Windows not appearing when opening file 2021-06-09 07:17:21 -03:00
LAGonauta 25673ab145 Use slight larger font on Windows so it matches Linux style
Also fixes some fuzzy fonts.
2021-06-09 07:17:21 -03:00
LAGonauta 8cb15fc325 Use ShellExecute instead of AppInfo to open files on Windows 2021-06-09 07:17:21 -03:00
LAGonauta 281a84a14c Add support for OpenPGP on Windows 2021-06-09 07:17:20 -03:00
LAGonauta e2fd821bb4 Add missing _WIN32 2021-06-09 07:17:20 -03:00
LAGonauta 0d384f83ae Added _WIN32 define to VALAC on Windows 2021-06-09 07:17:20 -03:00
LAGonauta 1841b348f1 Do not search for the built-in libraries when compiling with MINGW 2021-06-09 07:17:19 -03:00
LAGonauta 5f5b8fdfa0 fix build on newest MSYS2 2021-06-09 07:17:19 -03:00
LAGonauta eb7cf3297c Windows compatibility Tweaks 2021-06-09 07:17:18 -03:00
Martin Dosch 5d551360df Fix syntax error for setting AppID. 2020-11-06 14:12:50 +01:00
Martin Dosch a94acccd1d Add AppID (untested). 2020-10-29 13:47:26 +01:00
Martin Dosch d0d676e72d Add compression to achieve smaller installer size. 2020-09-18 16:51:41 +02:00
Martin Dosch 81721307ca Remove installation type "OpenPGP" support
This is no longer needed (see previous commit)
but was forgotten to remove in the previous
commit.
2020-07-10 17:04:13 +02:00
Martin Dosch 2d73f97d34 Removed compenent section
This section was only introduced to be able to
disable the OpenPGP plugin as Dino often crashed
on Windows if OpenPGP was not installed but the
plugin enabled.

This is no more necessary as the OpenPGP plugin
is now disabled by default.
2020-07-10 16:55:00 +02:00
Martin Dosch e24aa9aabc Add option to install without OpenPGP plugin 2020-06-28 09:00:03 +02:00
Martin Dosch 26a85ac109 Add german language. 2020-06-28 07:13:52 +02:00
Martin Dosch 8adf6731e7 Simplify installer script
The current build script already places the files in the right
folder structure so the installer doesn't have to do it itself
2020-05-19 08:38:17 +02:00
Martin Dosch 9154edaee1 Add dino logo again
The dino logo for the startmenu was accidentally
no longer included since the last commit.
2020-05-19 01:05:22 +02:00
Martin Dosch fd916bd6e6 Prevent duplicated DLLs 2020-05-19 00:55:14 +02:00
Martin Dosch 48619ee84d Add startmenu folder with several items
Added a startmenu folder with the following items:
* Dino launcher
* License
* Link to Dino website
* Uninstaller
2020-05-05 22:20:49 +02:00
Martin Dosch 70900cd73e Add license to windows installer 2020-05-05 19:17:45 +02:00
Martin Dosch 64260ee8c0 Merge branch 'master' into master-windows-changes 2020-05-03 11:11:19 +02:00
Martin Dosch 246000ce6a Fix typo in Dino slogan 2020-05-03 01:26:59 +02:00
Martin Dosch 9779abe701 Prepare signing
Collected some infos regarding signing
a windows build.
2020-05-03 01:01:30 +02:00
Martin Dosch 3ffec591a9 Revert "Prepare signing"
I copied the files into the wrong folder…
… it's late, sorry.

This reverts commit 7d6b9e7f4c.
2020-05-03 00:59:42 +02:00
Martin Dosch 7d6b9e7f4c Prepare signing
Collected some infos regarding signing
a windows build.
2020-05-03 00:55:59 +02:00
Martin Dosch 43f118bd4e Add experimental windows installer
This nsis script should create a windows installer.
Although the installer worked for the first tests
you should handle it with care and consider it
highly experimental
2020-05-02 22:03:20 +02:00
LAGonauta 057a72cd9f Windows compatibility Tweaks 2020-05-02 12:48:48 -03:00
136 changed files with 4305 additions and 56 deletions

26
.github/workflows/build-win64.yml vendored Normal file
View 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

View file

@ -9,7 +9,7 @@ jobs:
fetch-depth: 0
- run: sudo apt-get update
- 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: make
- run: build/xmpp-vala-test
@ -34,6 +34,7 @@ jobs:
- uses: actions/checkout@v2
with:
fetch-depth: 0
submodules: true
- uses: flatpak/flatpak-github-actions/flatpak-builder@v6.1
with:
manifest-path: im.dino.Dino.json

4
.gitignore vendored
View file

@ -6,3 +6,7 @@ Makefile
.idea
.sqlite3
gschemas.compiled
windows-installer/win64-dist/
*.exe
*.dll
.flatpak-builder

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "shared-modules"]
path = shared-modules
url = https://github.com/flathub/shared-modules.git

View file

@ -12,6 +12,12 @@ endif ()
# Prepare Plugins
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})
if ("$CACHE{DINO_PLUGIN_ENABLED_${plugin}}" STREQUAL "")
if (NOT DEFINED DINO_PLUGIN_ENABLED_${plugin}})
@ -176,6 +182,11 @@ if (NOT NO_DEBUG)
set(CMAKE_VALA_FLAGS "${CMAKE_VALA_FLAGS} -g")
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_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

56
README-WIN64.md Normal file
View 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
View 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
View 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

View file

@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback name)
# Found via pkg-config, using its result values
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
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)
if(NOT ${name}_${lib}_LIBRARY)
message(${name} ": " ${lib} " library not found")
unset(${name}_FOUND)
endif(NOT ${name}_${lib}_LIBRARY)
endforeach(lib)

View file

@ -13,11 +13,16 @@ function(find_pkg_config_with_fallback_on_config_script name)
# Found via pkg-config, using it's result values
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
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)
if(NOT ${name}_${lib}_LIBRARY)
message(${name} ": " ${lib} " library not found")
unset(${name}_FOUND)
endif(NOT ${name}_${lib}_LIBRARY)
endforeach(lib)

View file

@ -16,6 +16,7 @@
"--talk-name=org.freedesktop.Notifications"
],
"modules": [
"shared-modules/libcanberra/libcanberra.json",
{
"name": "libsignal-protocol-c",
"buildsystem": "cmake-ninja",

View file

@ -304,6 +304,24 @@ public class AvatarManager : StreamInteractionModule, Object {
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);
}
}
}

View file

@ -63,7 +63,7 @@ public class FileManager : StreamInteractionModule, Object {
try {
FileInfo file_info = file.query_info("*", FileQueryInfoFlags.NONE);
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.input_stream = yield file.read_async();
@ -259,9 +259,16 @@ public class FileManager : StreamInteractionModule, Object {
file_transfer.input_stream = yield file.read_async();
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;
#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) {
warning("Error downloading file: %s", e.message);
file_transfer.state = FileTransfer.State.FAILED;

View file

@ -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)) {
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()
@ -321,7 +352,7 @@ public class Dino.HistorySync {
* Iteratively fetches all pages returned for a query (until a PageResult other than MorePagesAvailable is returned)
* @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() : "");
PageRequestResult? page_result = null;
do {
@ -333,6 +364,8 @@ public class Dino.HistorySync {
string earliest_mam_id = page_result.query_result.first;
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);
var query = db.mam_catchup.update()
.with(db.mam_catchup.id, "=", db_id)
@ -344,6 +377,8 @@ public class Dino.HistorySync {
query.set(db.mam_catchup.from_end, true);
}
query.perform();
}
} while (page_result.page_result == PageResult.MorePagesAvailable);
return page_result;

View file

@ -12,9 +12,7 @@ public class NotificationEvents : StreamInteractionModule, Object {
public signal void notify_content_item(ContentItem content_item, Conversation conversation);
private StreamInteractor stream_interactor;
private Future<NotificationProvider> notifier;
private Promise<NotificationProvider> notifier_promise;
private bool notifier_outstanding = true;
private Gee.List<Promise<NotificationProvider>> promises = new ArrayList<Promise<NotificationProvider>>();
public static void start(StreamInteractor 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(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.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) {
if (notifier_outstanding || (yield notifier.wait_async()).get_priority() < notification_provider.get_priority()) {
notifier_outstanding = false;
notifier_promise.set_value(notification_provider);
}
var promise = new Promise<NotificationProvider>();
promise.set_value(notification_provider);
promises.add(promise);
}
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);
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);
}
}
break;
case FileItem.TYPE:
FileTransfer file_transfer = ((FileItem) item).file_transfer;
@ -91,9 +89,11 @@ public class NotificationEvents : StreamInteractionModule, Object {
notify_content_item(item, conversation);
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);
}
}
break;
case CallItem.TYPE:
// 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);
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);
}
}
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);
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);
}
}
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;
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);
call.notify["state"].connect(() => {
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) {
string inviter_display_name;
@ -139,21 +157,28 @@ public class NotificationEvents : StreamInteractionModule, Object {
Conversation direct_conversation = new Conversation(from_jid, account, Conversation.Type.CHAT);
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);
}
}
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);
}
}
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_conversation_notifications(conversation);
}
}
}
public interface NotificationProvider : Object {
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_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 notify_dialing();
public abstract async void retract_dialing();
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_muc_invite(Account account, Jid room_jid, Jid from_jid, string inviter_display_name);

View file

@ -71,6 +71,12 @@ public class Register : StreamInteractionModule, Object{
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 bool available { get; set; }
public TlsCertificateFlags? error_flags { get; set; }
@ -229,3 +235,4 @@ public class Register : StreamInteractionModule, Object{
}
}

View file

@ -4,6 +4,25 @@ using Qlite;
namespace Dino {
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) {
switch (conversation.type_) {
case Conversation.Type.CHAT:
@ -29,6 +48,33 @@ public class Util {
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();
}
}
}

View file

@ -78,6 +78,7 @@ set(RESOURCE_LIST
conversation_content_view/view.ui
manage_accounts/account_row.ui
manage_accounts/add_account_dialog.ui
manage_accounts/change_password_dialog.ui
manage_accounts/dialog.ui
menu_add.ui
menu_app.ui
@ -203,6 +204,7 @@ SOURCES
src/ui/contact_details/settings_provider.vala
src/ui/contact_details/permissions_provider.vala
src/ui/contact_details/history_provider.vala
src/ui/conversation_details.vala
@ -217,6 +219,7 @@ SOURCES
src/ui/manage_accounts/account_row.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/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")
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})
endif(WIN32)
add_dependencies(dino ${GETTEXT_PACKAGE}-translations)
target_include_directories(dino PRIVATE src)
target_link_libraries(dino libdino ${MAIN_PACKAGES})

View file

@ -58,6 +58,7 @@
<file>manage_accounts/account_row.ui</file>
<file>manage_accounts/add_account_dialog.ui</file>
<file>manage_accounts/dialog.ui</file>
<file>manage_accounts/change_password_dialog.ui</file>
<file>menu_add.ui</file>
<file>menu_app.ui</file>
<file>menu_conversation.ui</file>

View 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>

View file

@ -165,7 +165,17 @@
<layout>
<property name="column">1</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>
</object>
</child>

21
main/dino-info.rc Normal file
View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

View file

@ -39,6 +39,7 @@ sources = files(
'src/ui/chat_input/view.vala',
'src/ui/contact_details/permissions_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/chat_state_populator.vala',
'src/ui/conversation_content_view/content_populator.vala',
@ -71,6 +72,7 @@ sources = files(
'src/ui/main_window_controller.vala',
'src/ui/manage_accounts/account_row.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/notifier_freedesktop.vala',
'src/ui/notifier_gnotifications.vala',

View file

@ -1176,6 +1176,24 @@ msgstr "لقد أعددت كل شيء!"
msgid "Finish"
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."
#~ msgstr "اضغط هنا لبداية المحادثة أو للإنضمام إلى قناة."

View file

@ -1163,6 +1163,24 @@ msgstr "Tot llest!"
msgid "Finish"
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."
#~ msgstr "Feu clic aquí per a començar una conversa o unir-vos a un canal."

View file

@ -1166,5 +1166,22 @@ msgstr "Vše připraveno!"
msgid "Finish"
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."
#~ msgstr "Kliknutím sem zahájíte konverzaci nebo se připojíte ke kanálu."

View file

@ -1153,3 +1153,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1161,6 +1161,23 @@ msgstr "Fertig!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Klicke hier, um eine Unterhaltung zu starten oder einem Kanal beizutreten."

View file

@ -1154,3 +1154,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1169,6 +1169,23 @@ msgstr "Όλα έτοιμα!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Κάντε κλικ εδώ για να ξεκινήσετε μια συνομιλία ή να εισέλθετε σε ένα "

View file

@ -1144,3 +1144,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1162,6 +1162,24 @@ msgstr "Ĉio pretas!"
msgid "Finish"
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."
#~ msgstr "Alklaku ĉi tie por komenci konversacion aŭ aliĝi al kanalo."

View file

@ -1166,6 +1166,23 @@ msgstr "¡Todo listo!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Pulsar aquí para iniciar una conversación o unirse a un conversación en "

View file

@ -1165,6 +1165,23 @@ msgstr "Guztia ezarri da!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Klikatu hemen elkarrizketa berri bat hasi edo kanal batean sartzeko."

View file

@ -1161,6 +1161,23 @@ msgstr "همه تنظیم شده!"
msgid "Finish"
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."
#~ msgstr "برای شروع گفتگو یا پیوستن به کانال اینجا کلیک کنید."

View file

@ -1164,6 +1164,23 @@ msgstr ""
msgid "Finish"
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"
#~ msgstr "Ei aktiivisia keskusteluja"

View file

@ -1166,6 +1166,23 @@ msgstr "Tout est prêt!"
msgid "Finish"
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."
#~ msgstr "Cliquez ici pour commencer une discussion ou rejoindre un salon."

View file

@ -1166,6 +1166,23 @@ msgstr "Todo feito!"
msgid "Finish"
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."
#~ msgstr "Preme aquí para iniciar unha conversa ou unirte a unha canle."

View file

@ -1169,6 +1169,23 @@ msgstr "Minden készen áll!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Kattintson ide egy beszélgetés indításához vagy egy csatornához való "

View file

@ -1157,5 +1157,22 @@ msgstr "Selesai!"
msgid "Finish"
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."
#~ msgstr "Klik untuk memulai percakapan atau bergabung dengan channel."

View file

@ -1161,6 +1161,23 @@ msgstr "Omni es pret!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Fa un clic ti-ci por iniciar un conversation o adherer a un channel."

View file

@ -1161,5 +1161,22 @@ msgstr "Allt klárt!"
msgid "Finish"
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."
#~ msgstr "Smelltu hér til að hefja samtal eða taka þátt í rás."

View file

@ -1165,6 +1165,23 @@ msgstr "Tutto pronto!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Fai clic qui per iniziare una conversazione o per entrare in un canale."

View file

@ -1158,6 +1158,23 @@ msgstr "すべてのセットアップが完了しました!"
msgid "Finish"
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."
#~ msgstr ""
#~ "トークを始めたりトークルームに参加したりするには、ここをクリックしてくださ"

View file

@ -1153,3 +1153,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1166,5 +1166,22 @@ msgstr "모든 설정이 끝났습니다!"
msgid "Finish"
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."
#~ msgstr "대화를 시작하거나 채널에 들어가려면 여기를 누르세요."

View file

@ -1157,6 +1157,23 @@ msgstr "Alles ageriicht!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Klick hei fir eng Konversatioun ze starten oder engem Channel "

View file

@ -1169,6 +1169,23 @@ msgstr "Viskas nustatyta!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Spustelėkite čia norėdami pradėti pokalbį ar prisijungti prie kanalo."

View file

@ -1154,3 +1154,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1167,6 +1167,23 @@ msgstr "Ferdig oppsatt."
msgid "Finish"
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."
#~ msgstr "Klikk her for å starte en samtale, eller ta del i en kanal."

View file

@ -1163,6 +1163,23 @@ msgstr "Klaar!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Klik hier om een gesprek te starten of deel te nemen aan een kanaal."

View file

@ -1165,6 +1165,23 @@ msgstr "Tot es prèst!"
msgid "Finish"
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."
#~ msgstr "Clicatz aquí per començar una conversacion o jónher una sala."

View file

@ -1169,6 +1169,23 @@ msgstr "Wszystko gotowe!"
msgid "Finish"
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."
#~ msgstr "Kliknij tutaj, aby rozpocząć rozmowę albo dołączyć do kanału."

View file

@ -1163,5 +1163,22 @@ msgstr "Tudo configurado!"
msgid "Finish"
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."
#~ msgstr "Clique aqui para iniciar uma conversa or entrar num canal."

View file

@ -1164,6 +1164,23 @@ msgstr "Tudo configurado!"
msgid "Finish"
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."
#~ msgstr "Clique aqui para inicial uma conversa ou entrar em um canal."

View file

@ -1170,6 +1170,23 @@ msgstr "Gata!"
msgid "Finish"
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."
#~ msgstr ""
#~ "Apăsați aici pentru a porni o conversație sau a vă alătura unui canal."

View file

@ -1167,6 +1167,23 @@ msgstr "Всё готово!"
msgid "Finish"
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."
#~ msgstr "Нажмите здесь, чтобы начать беседу или присоединиться к каналу."

View file

@ -1163,5 +1163,22 @@ msgstr "Gjithçka e ujdisur!"
msgid "Finish"
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."
#~ msgstr "Klikoni këtu që të nisni një bisedë ose të hyni në një kanal."

View file

@ -1163,6 +1163,23 @@ msgstr "Färdigt!"
msgid "Finish"
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."
#~ msgstr "Klicka här för att starta en konversation eller gå med i en kanal."

View file

@ -1153,3 +1153,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1162,6 +1162,23 @@ msgstr "Hepsi tamam!"
msgid "Finish"
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."
#~ msgstr "Bir sohbet başlatmak ya da kanala katılmak için buraya tıkla."

View file

@ -1158,3 +1158,20 @@ msgstr ""
#: main/data/manage_accounts/add_account_dialog.ui:506
msgid "Finish"
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 ""

View file

@ -1155,6 +1155,23 @@ msgstr "都准备好了!"
msgid "Finish"
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."
#~ msgstr "点击此处以开始对话或加入频道。"

View file

@ -1154,6 +1154,23 @@ msgstr "全部設定好了!"
msgid "Finish"
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."
#~ msgstr "點擊此處開始對話或加入聊天室。"

View file

@ -9,6 +9,12 @@ namespace Dino {
void main(string[] args) {
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;
SearchPathGenerator search_path_generator = new SearchPathGenerator(exec_path);
Intl.textdomain(GETTEXT_PACKAGE);

View 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);
});
}
});
}
});
}
}
}

View file

@ -176,7 +176,7 @@ public class FileWidgetController : Object {
private void open_file() {
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) {
warning("Failed to open %s - %s", file_transfer.get_file().get_uri(), err.message);
}

View file

@ -242,7 +242,15 @@ public class MessageMetaItem : ContentMetaItem {
public static bool on_label_activate_link(string uri) {
// 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);
Dino.Application.get_default().open(new File[]{file}, "");
return true;

View file

@ -152,6 +152,7 @@ namespace Dino.Ui.ConversationDetails {
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.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) {
provider.populate(conversation, contact_details, Plugins.WidgetType.GTK4);

View file

@ -57,7 +57,7 @@ public class FileSendOverlay {
private async void load_file_widget(File file, FileInfo file_info) {
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;

View file

@ -373,7 +373,7 @@ public class AddAccountDialog : Gtk.Dialog {
// Button is opening a registration website
if (form.oob != null) {
try {
AppInfo.launch_default_for_uri(form.oob, null);
Dino.Util.launch_default_for_uri(form.oob);
} catch (Error e) { }
show_sign_in_jid();
return;

View 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");
}
}
}
}

View file

@ -25,6 +25,7 @@ public class Dialog : Gtk.Dialog {
[GtkChild] public unowned Label state_label;
[GtkChild] public unowned Switch active_switch;
[GtkChild] public unowned Util.EntryLabelHybrid password_hybrid;
[GtkChild] public unowned Button password_change_btn;
[GtkChild] public unowned Util.EntryLabelHybrid alias_hybrid;
[GtkChild] public unowned Grid settings_list;
@ -44,10 +45,12 @@ public class Dialog : Gtk.Dialog {
image_button.clicked.connect(show_select_avatar);
alias_hybrid.entry.changed.connect(() => { selected_account.alias = alias_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();
label_hybrid_group.add(alias_hybrid);
label_hybrid_group.add(password_hybrid);
password_change_btn.sensitive = false;
main_stack.set_visible_child_name("no_accounts");
@ -109,6 +112,12 @@ public class Dialog : Gtk.Dialog {
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) {
Gtk.MessageDialog msg = new Gtk.MessageDialog (
this, Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
@ -215,8 +224,10 @@ public class Dialog : Gtk.Dialog {
case ConnectionManager.ConnectionState.CONNECTING:
state_label.label = _("Connecting…"); break;
case ConnectionManager.ConnectionState.CONNECTED:
password_change_btn.sensitive = true;
state_label.label = _("Connected"); break;
case ConnectionManager.ConnectionState.DISCONNECTED:
password_change_btn.sensitive = false;
state_label.label = _("Disconnected"); break;
}
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) {
password_change_btn.sensitive = false;
switch (error.source) {
case ConnectionManager.ConnectionError.Source.SASL:
return _("Wrong password");

View file

@ -118,7 +118,6 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
HashTable<string, Variant> hash_table = new HashTable<string, Variant>(null, null);
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["desktop-entry"] = new Variant.string(Dino.Application.get_default().get_application_id());
hash_table["category"] = new Variant.string("im");
@ -153,6 +152,9 @@ public class Dino.Ui.FreeDesktopNotifier : NotificationProvider, Object {
} catch (Error e) { }
}
public async void notify_dialing(){}
public async void retract_dialing(){}
public async void notify_subscription_request(Conversation conversation) {
string summary = _("Subscription request");
string body = Markup.escape_text(conversation.counterpart.to_string());

View file

@ -87,6 +87,9 @@ namespace Dino.Ui {
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) {
Notification notification = new Notification(_("Subscription request"));
notification.set_body(conversation.counterpart.to_string());

View file

@ -1,3 +1,7 @@
if(WIN32)
add_link_options("-Wl,--export-all-symbols")
endif(WIN32)
foreach(plugin ${PLUGINS})
add_subdirectory(${plugin})
endforeach(plugin)

View file

@ -177,6 +177,13 @@ private static uint8[] get_uint8_from_data(Data data) {
private static void initialize() {
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();
initialized = true;
}

View file

@ -665,6 +665,9 @@ namespace GPG {
[CCode (cname = "gpgme_strerror")]
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 {
if (error.code != GPGError.ErrorCode.NO_ERROR) {
throw new GLib.Error(-1, error.code, "%s", error.to_string());

View 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})

View 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){}
}
}

View file

@ -0,0 +1,3 @@
public Type register_plugin(Module module) {
return typeof (Dino.Plugins.PhoneRinger.Plugin);
}

View file

@ -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.start();
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.get_string("device.class") == "monitor") 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();
}
destroy_call_pipe();
Gst.deinit();
}
public bool supports(string? media) {

View 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})

View file

@ -0,0 +1,3 @@
* {
font-size: 1.125rem;
}

View 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() { }
}
}

View file

@ -0,0 +1,3 @@
public Type register_plugin(Module module) {
return typeof (Dino.Plugins.Win32Fonts.Plugin);
}

View file

@ -0,0 +1 @@
/yolort

View 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})

View 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

View 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);

View 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

View 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

View file

@ -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__ */

View file

@ -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__ */

View file

@ -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__ */

View file

@ -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__ */

View file

@ -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__ */

View file

@ -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__ */

View file

@ -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