aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md6
-rw-r--r--TODO4
m---------depends/html-parser0
m---------depends/html-search0
m---------depends/jsoncpp0
m---------depends/mglpp0
m---------depends/rapidjson0
-rw-r--r--include/ImageViewer.hpp2
-rw-r--r--include/QuickMedia.hpp1
-rw-r--r--include/Storage.hpp1
-rwxr-xr-xinstall.sh36
-rw-r--r--meson.build138
-rw-r--r--meson_options.txt3
-rwxr-xr-xmeson_post_install.sh6
-rw-r--r--plugins/Matrix.hpp11
-rw-r--r--project.conf2
-rw-r--r--src/AsyncImageLoader.cpp1
-rw-r--r--src/FileAnalyzer.cpp2
-rw-r--r--src/ImageViewer.cpp25
-rw-r--r--src/QuickMedia.cpp21
-rw-r--r--src/Storage.cpp15
-rw-r--r--src/main.cpp2
-rw-r--r--src/plugins/Matrix.cpp42
-rw-r--r--uninstall.sh10
m---------video_player/jsoncpp0
25 files changed, 268 insertions, 60 deletions
diff --git a/README.md b/README.md
index c9781ff..1db226e 100644
--- a/README.md
+++ b/README.md
@@ -24,9 +24,8 @@ EXAMPLES:
tabbed -c -k quickmedia launcher -e
```
## Installation
-If you are running arch linux then you can install QuickMedia from aur: [https://aur.archlinux.org/packages/quickmedia-git/](https://aur.archlinux.org/packages/quickmedia-git/), otherwise you will need to first install [sibs](https://git.dec05eba.com/sibs/) and then run `./install.sh` as root.\
+If you are running arch linux then you can install QuickMedia from aur: [https://aur.archlinux.org/packages/quickmedia-git/](https://aur.archlinux.org/packages/quickmedia-git/), otherwise you will need to run `./install.sh` as root.\
`tar` and curl needs to be installed to run the `install.sh` script.\
-Installing `lld` (the LLVM linker) can improve compile times.\
There is also an unofficial ebuild for gentoo users. On gentoo you can install QuickMedia by running these commands:
```bash
eselect repository add overlay-from-plan9 git https://git.plan9.rocks/cat/overlay-from-plan9
@@ -34,6 +33,7 @@ emerge --sync overlay-from-plan9
emerge -av quickmedia
```
## Dependencies
+Meson needs to be installed to run the build script.
### Libraries
`libglvnd (LibGL.so)`, `libx11`, `libxrandr`, `libmpv`
### Executables
@@ -105,6 +105,7 @@ Type text and then wait and QuickMedia will automatically search.\
`Home`: Go to the first page.\
`End`: Go to the last page.\
`F`: Toggle between scaling the image to the window size or only down scaling if the image is too large.\
+`B`: Show/hide the bottom progress bar.\
`I`: Switch to scroll view.
### Manga scroll view controls
`Arrow up`/`K`: Move up.\
@@ -113,6 +114,7 @@ Type text and then wait and QuickMedia will automatically search.\
`Home`: Go to the first page.\
`End`: Go to the last page.\
`F`: Toggle between scaling the image to the window size or only down scaling if the image is too large.\
+`B`: Show/hide the bottom progress bar.\
`I`: Switch to page view.
### Manga chapters controls
`Ctrl+T`: Start tracking the manga after the selected chapter ([AutoMedia](https://git.dec05eba.com/AutoMedia/) needs to be installed).
diff --git a/TODO b/TODO
index 195e17b..97d53c3 100644
--- a/TODO
+++ b/TODO
@@ -297,4 +297,6 @@ v0.m3u8 doesn't work for some lbry videos (such as https://odysee.com/@MoneroMag
Use DPMSInfoNotify.
Use stb_image_resize2.h
Youtube audio only download if audio stream not available, also for youtube-dl fallback.
-Make history (local-manga and others) use relative path to the downloads directory for thumbnails. Otherwise the thumbnails wont show when moving the download directory. \ No newline at end of file
+Make history (local-manga and others) use relative path to the downloads directory for thumbnails. Otherwise the thumbnails wont show when moving the download directory.
+Keep the rooms that we were kicked/banned from so we can still read them and re-read the reason for why we were kicked/banned. Or add a list of historical rooms with leave reason.
+Fix youtube broken (always falls back to low quality yt-dlp). \ No newline at end of file
diff --git a/depends/html-parser b/depends/html-parser
-Subproject ec0e71c259d5aa8be7b8456509b5617d27742b6
+Subproject 3cf44ec7fba308a4b33b0486545b33e334bed74
diff --git a/depends/html-search b/depends/html-search
-Subproject 68989816f43ceda8655c2dbdc0d581971e645fc
+Subproject a77706c37d3b6df3049f658dd220b813fe1834b
diff --git a/depends/jsoncpp b/depends/jsoncpp
-Subproject f23fb32fd9d9c3d01fa67afa0d75f7ff227647e
+Subproject 98e28b38ffbae24c0e69e620bf18f8a0c5c6f20
diff --git a/depends/mglpp b/depends/mglpp
-Subproject 1a2a6ad8ef354f62bdf9adcfef73af1e5d03695
+Subproject 9634e4fef56016f59d45b0cb530087ab36f0171
diff --git a/depends/rapidjson b/depends/rapidjson
-Subproject a42f7cc32be7c1d2100d30098e15ff2661c4a61
+Subproject 49b4e2dc7892f27b56a5a9f058c2c9969609324
diff --git a/include/ImageViewer.hpp b/include/ImageViewer.hpp
index b587b82..b3b18dc 100644
--- a/include/ImageViewer.hpp
+++ b/include/ImageViewer.hpp
@@ -104,5 +104,7 @@ namespace QuickMedia {
mgl::vec2d prev_size_first_page;
mgl::vec2d prev_size_last_page;
+
+ bool show_progress_bar = true;
};
} \ No newline at end of file
diff --git a/include/QuickMedia.hpp b/include/QuickMedia.hpp
index a6de75c..038cf19 100644
--- a/include/QuickMedia.hpp
+++ b/include/QuickMedia.hpp
@@ -245,5 +245,6 @@ namespace QuickMedia {
std::mutex login_inputs_mutex;
const char *yt_dl_name = nullptr;
bool yt_dl_name_checked = false;
+ bool show_manga_bottom_bar = true;
};
}
diff --git a/include/Storage.hpp b/include/Storage.hpp
index 60c15f6..86c34d2 100644
--- a/include/Storage.hpp
+++ b/include/Storage.hpp
@@ -34,6 +34,7 @@ namespace QuickMedia {
bool file_get_last_modified_time_seconds(const char *path, time_t *result);
int file_overwrite(const Path &path, const std::string &data);
int file_overwrite_atomic(const Path &path, const std::string &data);
+ bool file_append(const Path &path, const std::string &data);
// The callback is called with 0 as the argument (last_modified_seconds)
void for_files_in_dir(const Path &path, FileIteratorCallback callback);
void for_files_in_dir_sort_last_modified(const Path &path, FileIteratorCallback callback, FileSortDirection sort_dir = FileSortDirection::ASC);
diff --git a/install.sh b/install.sh
index 64ee28f..e8743e4 100755
--- a/install.sh
+++ b/install.sh
@@ -5,35 +5,9 @@ cd "$script_dir"
[ $(id -u) -ne 0 ] && echo "You need root privileges to run the install script" && exit 1
-curl -sfL 'https://dec05eba.com/files/twemoji.tar.gz' -o /tmp/twemoji.tar.gz
-mkdir -p /usr/share/quickmedia/emoji
-tar xf /tmp/twemoji.tar.gz --directory=/usr/share/quickmedia/emoji
-rm -f /tmp/twemoji.tar.gz
+rm -rf build
+meson setup build
+meson configure --prefix=/usr --buildtype=release -Dstrip=true build
+ninja -C build install
-sibs build --release video_player
-sibs build --release
-
-install -Dm755 "video_player/sibs-build/$(sibs platform)/release/quickmedia-video-player" "/usr/bin/quickmedia-video-player"
-install -Dm755 "sibs-build/$(sibs platform)/release/quickmedia" "/usr/bin/quickmedia"
-ln -sf "/usr/bin/quickmedia" "/usr/bin/qm"
-install -Dm644 boards.json "/usr/share/quickmedia/boards.json"
-
-install -Dm644 example-config.json "/usr/share/quickmedia/example-config.json"
-install -Dm644 README.md "/usr/share/quickmedia/README.md"
-
-install -Dm644 mpv/fonts/Material-Design-Iconic-Font.ttf "/usr/share/quickmedia/mpv/fonts/Material-Design-Iconic-Font.ttf"
-install -Dm644 mpv/scripts/mordenx.lua "/usr/share/quickmedia/mpv/scripts/mordenx.lua"
-install -Dm644 mpv/scripts/ytdl_hook.lua "/usr/share/quickmedia/mpv/scripts/ytdl_hook.lua"
-install -Dm644 mpv/input.conf "/usr/share/quickmedia/mpv/input.conf"
-install -Dm644 mpv/mpv.conf "/usr/share/quickmedia/mpv/mpv.conf"
-
-for file in images/* icons/* shaders/* themes/*; do
- install -Dm644 "$file" "/usr/share/quickmedia/$file"
-done
-
-for file in launcher/*; do
- filename=$(basename "$file")
- install -Dm644 "$file" "/usr/share/applications/$filename"
-done
-
-echo "Successfully installed QuickMedia"
+echo "Successfully installed quickmedia" \ No newline at end of file
diff --git a/meson.build b/meson.build
new file mode 100644
index 0000000..a675ac8
--- /dev/null
+++ b/meson.build
@@ -0,0 +1,138 @@
+project('quickmedia', ['c', 'cpp'], version : '1.0.0', default_options : ['warning_level=2', 'cpp_std=c++17'], subproject_dir : 'depends')
+
+if get_option('buildtype') == 'debug'
+ add_project_arguments('-g3', language : ['c', 'cpp'])
+elif get_option('buildtype') == 'release'
+ add_project_arguments('-DNDEBUG', language : ['c', 'cpp'])
+endif
+
+src = [
+ 'external/hash-library/sha256.cpp',
+ 'generated/Tlds.cpp',
+ 'generated/Emoji.cpp',
+ 'src/plugins/utils/aes.c',
+ 'src/plugins/Fourchan.cpp',
+ 'src/plugins/Mangadex.cpp',
+ 'src/plugins/ImageBoard.cpp',
+ 'src/plugins/MangaCombined.cpp',
+ 'src/plugins/Manga.cpp',
+ 'src/plugins/Lbry.cpp',
+ 'src/plugins/NyaaSi.cpp',
+ 'src/plugins/HotExamples.cpp',
+ 'src/plugins/FileManager.cpp',
+ 'src/plugins/MediaGeneric.cpp',
+ 'src/plugins/Matrix.cpp',
+ 'src/plugins/Plugin.cpp',
+ 'src/plugins/MangaGeneric.cpp',
+ 'src/plugins/Pipe.cpp',
+ 'src/plugins/Manganelo.cpp',
+ 'src/plugins/LocalManga.cpp',
+ 'src/plugins/Page.cpp',
+ 'src/plugins/Peertube.cpp',
+ 'src/plugins/LocalAnime.cpp',
+ 'src/plugins/AniList.cpp',
+ 'src/plugins/DramaCool.cpp',
+ 'src/plugins/utils/UniqueProcess.cpp',
+ 'src/plugins/utils/WatchProgress.cpp',
+ 'src/plugins/utils/EpisodeNameParser.cpp',
+ 'src/plugins/Info.cpp',
+ 'src/plugins/Youtube.cpp',
+ 'src/plugins/Saucenao.cpp',
+ 'src/plugins/Soundcloud.cpp',
+ 'src/Theme.cpp',
+ 'src/Storage.cpp',
+ 'src/Text.cpp',
+ 'src/Config.cpp',
+ 'src/DownloadUtils.cpp',
+ 'src/Json.cpp',
+ 'src/gui/Button.cpp',
+ 'src/SearchBar.cpp',
+ 'src/RoundedRectangle.cpp',
+ 'src/Entry.cpp',
+ 'src/Notification.cpp',
+ 'src/AsyncImageLoader.cpp',
+ 'src/ImageViewer.cpp',
+ 'src/Body.cpp',
+ 'src/Program.cpp',
+ 'src/main.cpp',
+ 'src/ImageUtils.cpp',
+ 'src/NetUtils.cpp',
+ 'src/BodyItem.cpp',
+ 'src/Downloader.cpp',
+ 'src/ResourceLoader.cpp',
+ 'src/VideoPlayer.cpp',
+ 'src/Tabs.cpp',
+ 'src/FileAnalyzer.cpp',
+ 'src/QuickMedia.cpp',
+ 'src/M3U8.cpp',
+ 'src/Utils.cpp',
+ 'src/StringUtils.cpp',
+]
+
+mglpp_proj = subproject('mglpp')
+mglpp_dep = mglpp_proj.get_variable('mglpp_dep')
+
+jsoncpp_proj = subproject('jsoncpp')
+jsoncpp_dep = jsoncpp_proj.get_variable('jsoncpp_dep')
+
+rapidjson_proj = subproject('rapidjson')
+rapidjson_dep = rapidjson_proj.get_variable('rapidjson_dep')
+
+html_parser_proj = subproject('html-parser')
+html_parser_dep = html_parser_proj.get_variable('html_parser_dep')
+
+html_search_proj = subproject('html-search')
+html_search_dep = html_search_proj.get_variable('html_search_dep')
+
+prefix = get_option('prefix')
+datadir = get_option('datadir')
+qm_resources_path = join_paths(prefix, datadir, 'quickmedia')
+
+if get_option('native_arch') == true
+ add_project_arguments('-march=native', language: ['c', 'cpp'])
+endif
+
+executable(
+ meson.project_name(),
+ src,
+ install : true,
+ dependencies : [
+ mglpp_dep,
+ jsoncpp_dep,
+ rapidjson_dep,
+ html_parser_dep,
+ html_search_dep,
+ dependency('threads'),
+ ],
+)
+
+executable(
+ 'quickmedia-video-player',
+ [
+ 'video_player/src/main.cpp'
+ ],
+ install : true,
+ dependencies : [
+ jsoncpp_dep,
+ dependency('mpv'),
+ ],
+)
+
+install_subdir('mpv', install_dir : qm_resources_path)
+install_subdir('images', install_dir : qm_resources_path)
+install_subdir('icons', install_dir : qm_resources_path)
+install_subdir('shaders', install_dir : qm_resources_path)
+install_subdir('themes', install_dir : qm_resources_path)
+
+install_data('launcher/QuickMedia.desktop', install_dir : join_paths(prefix, datadir, 'applications'))
+install_data(files('boards.json'), install_dir : qm_resources_path)
+install_data(files('example-config.json'), install_dir : qm_resources_path)
+install_data(files('README.md'), install_dir : qm_resources_path)
+
+if get_option('install_symlink') == true
+ install_symlink('qm', install_dir : join_paths(prefix, 'bin'), pointing_to: join_paths(prefix, 'bin', meson.project_name()))
+endif
+
+if get_option('install_emoji') == true
+ meson.add_install_script('meson_post_install.sh')
+endif
diff --git a/meson_options.txt b/meson_options.txt
new file mode 100644
index 0000000..0232def
--- /dev/null
+++ b/meson_options.txt
@@ -0,0 +1,3 @@
+option('native_arch', type : 'boolean', value : true, description : 'Build specifically for your own cpu for best performance')
+option('install_symlink', type : 'boolean', value : true, description : 'Install a symlink for qm to quickmedia')
+option('install_emoji', type : 'boolean', value : true, description : 'Download and install emoji')
diff --git a/meson_post_install.sh b/meson_post_install.sh
new file mode 100755
index 0000000..1c87f9f
--- /dev/null
+++ b/meson_post_install.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+curl -sfL 'https://dec05eba.com/files/twemoji.tar.gz' -o /tmp/twemoji.tar.gz
+mkdir -p "${MESON_INSTALL_DESTDIR_PREFIX}/share/quickmedia/emoji"
+tar xf /tmp/twemoji.tar.gz --directory="${MESON_INSTALL_DESTDIR_PREFIX}/share/quickmedia/emoji"
+rm -f /tmp/twemoji.tar.gz \ No newline at end of file
diff --git a/plugins/Matrix.hpp b/plugins/Matrix.hpp
index a3ce633..23b0a8a 100644
--- a/plugins/Matrix.hpp
+++ b/plugins/Matrix.hpp
@@ -320,7 +320,7 @@ namespace QuickMedia {
virtual ~MatrixDelegate() = default;
virtual void join_room(RoomData *room) = 0;
- virtual void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) = 0;
+ virtual void leave_room(RoomData *room, const std::string &event_id, LeaveType leave_type, const std::string &reason) = 0;
// Note: calling |room| methods inside this function is not allowed
virtual void room_add_tag(RoomData *room, const std::string &tag) = 0;
@@ -356,7 +356,7 @@ namespace QuickMedia {
MatrixQuickMedia(Program *program, Matrix *matrix, MatrixRoomsPage *rooms_page, MatrixRoomTagsPage *room_tags_page, MatrixInvitesPage *invites_page, MatrixNotificationsPage *notifications_page);
void join_room(RoomData *room) override;
- void leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) override;
+ void leave_room(RoomData *room, const std::string &event_id, LeaveType leave_type, const std::string &reason) override;
void room_add_tag(RoomData *room, const std::string &tag) override;
void room_remove_tag(RoomData *room, const std::string &tag) override;
void room_add_new_messages(RoomData *room, const Messages &messages, bool is_initial_sync, MessageDirection message_dir) override;
@@ -759,6 +759,11 @@ namespace QuickMedia {
MatrixDelegate* get_delegate();
+ bool is_another_instance_running() const { return matrix_instance_already_running; }
+
+ void mark_other_notification_as_read(const std::string &event_id);
+ bool is_other_notification_read(const std::string &event_id) const;
+
// Calls the |MatrixDelegate| pending events.
// Should be called from the main (ui) thread
void update();
@@ -783,6 +788,7 @@ namespace QuickMedia {
void add_new_invites();
void parse_custom_emoji(const rapidjson::Value &custom_emoji_json);
void load_custom_emoji_from_cache();
+ void load_other_notifications();
PluginResult get_previous_room_messages(RoomData *room_data, bool latest_messages, size_t &num_new_messages, bool *reached_end = nullptr);
void events_add_user_info(const rapidjson::Value &events_json, RoomData *room_data, int64_t timestamp);
std::shared_ptr<UserInfo> parse_user_info(const rapidjson::Value &json, const std::string &user_id, RoomData *room_data, int64_t timestamp);
@@ -850,6 +856,7 @@ namespace QuickMedia {
std::unordered_map<std::string, CustomEmoji> custom_emoji_by_key;
std::unordered_set<std::string> silenced_invites;
std::unordered_map<std::string, int64_t> qm_read_markers_by_room_cache;
+ std::unordered_set<std::string> other_notifications_read;
MessageQueue<std::shared_ptr<MatrixChatBodyDecryptJob>> decrypt_task;
std::thread decrypt_thread;
diff --git a/project.conf b/project.conf
index b737123..5f01694 100644
--- a/project.conf
+++ b/project.conf
@@ -7,7 +7,7 @@ platforms = ["posix"]
[config]
# This needs to be commented out for now because rapidjson depends on undefined behavior according to gcc...
#error_on_warning = "true"
-ignore_dirs = ["video_player"]
+ignore_dirs = ["video_player", "build"]
[lang.cpp]
version = "c++17"
diff --git a/src/AsyncImageLoader.cpp b/src/AsyncImageLoader.cpp
index 14cfe6a..a6706f5 100644
--- a/src/AsyncImageLoader.cpp
+++ b/src/AsyncImageLoader.cpp
@@ -27,6 +27,7 @@
namespace QuickMedia {
bool ffmpeg_convert_image_format(const Path &thumbnail_path, const Path &destination_path) {
+ // TODO: Dont output as jpg, ffmpeg jpg is very slow
const char *args[] = { "ffmpeg", "-y", "-v", "quiet", "-i", thumbnail_path.data.c_str(), "--", destination_path.data.c_str(), nullptr};
return exec_program(args, nullptr, nullptr) == 0;
}
diff --git a/src/FileAnalyzer.cpp b/src/FileAnalyzer.cpp
index 4deb8c3..1d24c5f 100644
--- a/src/FileAnalyzer.cpp
+++ b/src/FileAnalyzer.cpp
@@ -157,6 +157,7 @@ namespace QuickMedia {
char size_arg_str[512];
snprintf(size_arg_str, sizeof(size_arg_str), "scale=%d:%d:force_original_aspect_ratio=decrease", width, height);
+ // TODO: Dont output as jpg, ffmpeg jpg is very slow
const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", seconds_str, "-i", file.get_filepath().c_str(), "-frames:v", "1", "-vf", size_arg_str, "--", destination_path_tmp.data.c_str(), nullptr };
if(exec_program(program_args, nullptr, nullptr, allowed_exit_status, 2) != 0) {
fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n");
@@ -168,6 +169,7 @@ namespace QuickMedia {
if(fallback_first_frame && get_file_type(destination_path_tmp) == FileType::FILE_NOT_FOUND)
return video_get_frame(file, destination_path, width, height, 0, false);
} else {
+ // TODO: Dont output as jpg, ffmpeg jpg is very slow
const char *program_args[] = { "ffmpeg", "-y", "-v", "quiet", "-ss", seconds_str, "-i", file.get_filepath().c_str(), "-frames:v", "1", "--", destination_path_tmp.data.c_str(), nullptr };
if(exec_program(program_args, nullptr, nullptr, allowed_exit_status, 2) != 0) {
fprintf(stderr, "Failed to execute ffmpeg, maybe its not installed?\n");
diff --git a/src/ImageViewer.cpp b/src/ImageViewer.cpp
index fb9912c..454f34b 100644
--- a/src/ImageViewer.cpp
+++ b/src/ImageViewer.cpp
@@ -296,6 +296,9 @@ namespace QuickMedia {
if(event.key.code == mgl::Keyboard::F)
*fit_image_to_window = !*fit_image_to_window;
+
+ if(event.key.code == mgl::Keyboard::B)
+ show_progress_bar = !show_progress_bar;
} else if(event.type == mgl::Event::KeyReleased) {
if(is_key_scroll_up(event.key))
up_pressed = false;
@@ -426,16 +429,18 @@ namespace QuickMedia {
const float font_height = page_text_character_size + 8.0f;
const float background_height = font_height + 6.0f;
- mgl::Rectangle page_text_background(mgl::vec2f(window_size.x, background_height));
- mgl::Color text_background_color = get_theme().shade_color;
- text_background_color.a = 225;
- page_text_background.set_color(text_background_color);
- page_text_background.set_position(mgl::vec2f(0.0f, window_size.y - background_height));
- window->draw(page_text_background);
-
- auto page_text_bounds = page_text.get_bounds();
- page_text.set_position(mgl::vec2f(floor(window_size.x * 0.5f - page_text_bounds.size.x * 0.5f), floor(window_size.y - background_height * 0.5f - font_height * 0.55f)));
- window->draw(page_text);
+ if(show_progress_bar) {
+ mgl::Rectangle page_text_background(mgl::vec2f(window_size.x, background_height));
+ mgl::Color text_background_color = get_theme().shade_color;
+ text_background_color.a = 225;
+ page_text_background.set_color(text_background_color);
+ page_text_background.set_position(mgl::vec2f(0.0f, window_size.y - background_height));
+ window->draw(page_text_background);
+
+ auto page_text_bounds = page_text.get_bounds();
+ page_text.set_position(mgl::vec2f(floor(window_size.x * 0.5f - page_text_bounds.size.x * 0.5f), floor(window_size.y - background_height * 0.5f - font_height * 0.55f)));
+ window->draw(page_text);
+ }
// Free pages that are not visible on the screen
int i = 0;
diff --git a/src/QuickMedia.cpp b/src/QuickMedia.cpp
index f3e21da..0671349 100644
--- a/src/QuickMedia.cpp
+++ b/src/QuickMedia.cpp
@@ -953,7 +953,7 @@ namespace QuickMedia {
string_split(urls_str, ',', [&arrays](const char *str, size_t size) {
std::string url(str, size);
url = strip(url);
- if(!url.empty() && (arrays.empty() || arrays.back() != url))
+ if(url.find(".com") != std::string::npos && (arrays.empty() || arrays.back() != url))
arrays.push_back(std::move(url));
return true;
});
@@ -4490,6 +4490,9 @@ namespace QuickMedia {
} else if(event.key.code == mgl::Keyboard::F) {
fit_image_to_window = !fit_image_to_window;
redraw = true;
+ } else if(event.key.code == mgl::Keyboard::B) {
+ show_manga_bottom_bar = !show_manga_bottom_bar;
+ redraw = true;
}
}
}
@@ -4514,7 +4517,7 @@ namespace QuickMedia {
}
const float font_height = chapter_text_character_size + 8.0f;
- const float bottom_panel_height = font_height + 6.0f;
+ const float bottom_panel_height = show_manga_bottom_bar ? font_height + 6.0f : 0.0f;
mgl::vec2f content_size;
content_size.x = window_size.x;
@@ -4553,13 +4556,15 @@ namespace QuickMedia {
window.draw(image);
}
- chapter_text_background.set_size(mgl::vec2f(window_size.x, bottom_panel_height));
- chapter_text_background.set_position(mgl::vec2f(0.0f, std::floor(window_size.y - bottom_panel_height)));
- window.draw(chapter_text_background);
+ if(show_manga_bottom_bar) {
+ chapter_text_background.set_size(mgl::vec2f(window_size.x, bottom_panel_height));
+ chapter_text_background.set_position(mgl::vec2f(0.0f, std::floor(window_size.y - bottom_panel_height)));
+ window.draw(chapter_text_background);
- auto text_bounds = chapter_text.get_bounds();
- chapter_text.set_position(vec2f_floor(window_size.x * 0.5f - text_bounds.size.x * 0.5f, window_size.y - bottom_panel_height * 0.5f - font_height * 0.55f));
- window.draw(chapter_text);
+ auto text_bounds = chapter_text.get_bounds();
+ chapter_text.set_position(vec2f_floor(window_size.x * 0.5f - text_bounds.size.x * 0.5f, window_size.y - bottom_panel_height * 0.5f - font_height * 0.55f));
+ window.draw(chapter_text);
+ }
window.display();
} else {
diff --git a/src/Storage.cpp b/src/Storage.cpp
index 7bb3be6..5c12911 100644
--- a/src/Storage.cpp
+++ b/src/Storage.cpp
@@ -244,6 +244,21 @@ namespace QuickMedia {
return rename_atomic(tmp_path.data.c_str(), path.data.c_str());
}
+ bool file_append(const Path &path, const std::string &data) {
+ FILE *file = fopen_eintr(path.data.c_str(), "ab");
+ if(!file) {
+ perror(path.data.c_str());
+ return false;
+ }
+
+ if(fwrite_eintr(data.data(), data.size(), file) != data.size()) {
+ fclose(file);
+ return false;
+ }
+
+ return fclose(file) == 0;
+ }
+
void for_files_in_dir(const Path &path, FileIteratorCallback callback) {
try {
for(auto &p : std::filesystem::directory_iterator(path.data)) {
diff --git a/src/main.cpp b/src/main.cpp
index ef0568b..b09cf14 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,8 +1,10 @@
#include "../include/QuickMedia.hpp"
#include <locale.h>
+#include <malloc.h>
int main(int argc, char **argv) {
setlocale(LC_ALL, "C"); // Sigh... stupid C
+ // mallopt(M_MMAP_THRESHOLD, 65536);
QuickMedia::Program program;
return program.run(argc, argv);
}
diff --git a/src/plugins/Matrix.cpp b/src/plugins/Matrix.cpp
index 1b43b2d..7080bf9 100644
--- a/src/plugins/Matrix.cpp
+++ b/src/plugins/Matrix.cpp
@@ -629,12 +629,15 @@ namespace QuickMedia {
rooms_page->add_body_item(body_item);
}
- void MatrixQuickMedia::leave_room(RoomData *room, LeaveType leave_type, const std::string &reason) {
+ void MatrixQuickMedia::leave_room(RoomData *room, const std::string &event_id, LeaveType leave_type, const std::string &reason) {
room_body_item_by_room.erase(room);
rooms_page->remove_body_item_by_room_id(room->id);
room_tags_page->remove_body_item_by_room_id(room->id);
- if(leave_type != LeaveType::LEAVE)
+ if(leave_type != LeaveType::LEAVE && (event_id.empty() || !matrix->is_other_notification_read(event_id))) {
show_notification("QuickMedia", reason);
+ if(!event_id.empty())
+ matrix->mark_other_notification_as_read(event_id);
+ }
}
void MatrixQuickMedia::room_add_tag(RoomData *room, const std::string &tag) {
@@ -1674,6 +1677,7 @@ namespace QuickMedia {
load_silenced_invites();
load_custom_emoji_from_cache();
+ load_other_notifications();
sync_thread = std::thread([this, matrix_cache_dir]() {
FILE *sync_cache_file;
@@ -1858,8 +1862,8 @@ namespace QuickMedia {
fwrite(json_data.data(), 1, json_data.size(), sync_cache_file);
file_overwrite(get_cache_dir().join("matrix").join(update_cache_file_name), "1"); // To make sure the cache format is up to date
- malloc_trim(0);
}
+ malloc_trim(0);
fclose(sync_cache_file);
}
}
@@ -2208,6 +2212,18 @@ namespace QuickMedia {
parse_custom_emoji(json_root);
}
+ void Matrix::load_other_notifications() {
+ std::string result;
+ if(file_get_content(get_storage_dir().join("matrix").join("other_notifications_read"), result) != 0)
+ return;
+
+ other_notifications_read.clear();
+ string_split_view(result, '\n', [this](const char *str, size_t line) {
+ other_notifications_read.insert(std::string(str, line));
+ return true;
+ });
+ }
+
PluginResult Matrix::parse_sync_account_data(const rapidjson::Value &account_data_json) {
if(!account_data_json.IsObject())
return PluginResult::OK;
@@ -3884,6 +3900,10 @@ namespace QuickMedia {
if(!type_json.IsString() || strcmp(type_json.GetString(), "m.room.member") != 0)
continue;
+ const rapidjson::Value &event_id_json = GetMember(event_json, "event_id");
+ if(!event_id_json.IsString())
+ continue;
+
const rapidjson::Value &sender_json = GetMember(event_json, "sender");
if(!sender_json.IsString())
continue;
@@ -3924,7 +3944,10 @@ namespace QuickMedia {
if(!reason_str.empty())
desc += ", reason: " + reason_str;
- ui_thread_tasks.push([this, room, leave_type, desc{std::move(desc)}]{ delegate->leave_room(room, leave_type, desc); });
+ std::string event_id_str = event_id_json.GetString();
+ ui_thread_tasks.push([this, room, event_id_str{std::move(event_id_str)}, leave_type, desc{std::move(desc)}]{
+ delegate->leave_room(room, event_id_str, leave_type, desc);
+ });
remove_room(room_id_str);
break;
}
@@ -4213,6 +4236,15 @@ namespace QuickMedia {
return delegate;
}
+ void Matrix::mark_other_notification_as_read(const std::string &event_id) {
+ other_notifications_read.insert(event_id);
+ file_append(get_storage_dir().join("matrix").join("other_notifications_read"), event_id + "\n");
+ }
+
+ bool Matrix::is_other_notification_read(const std::string &event_id) const {
+ return other_notifications_read.find(event_id) != other_notifications_read.end();
+ }
+
PluginResult Matrix::post_message(RoomData *room, const std::string &body, std::string &event_id_response, const std::optional<UploadInfo> &file_info, const std::optional<UploadInfo> &thumbnail_info, const std::string &msgtype, const std::string &custom_transaction_id) {
std::string transaction_id = custom_transaction_id;
if(transaction_id.empty())
@@ -5629,7 +5661,7 @@ namespace QuickMedia {
if(download_result == DownloadResult::OK) {
RoomData *room = get_room_by_id(room_id);
if(room) {
- ui_thread_tasks.push([this, room]{ delegate->leave_room(room, LeaveType::LEAVE, ""); });
+ ui_thread_tasks.push([this, room]{ delegate->leave_room(room, "", LeaveType::LEAVE, ""); });
remove_room(room_id);
}
}
diff --git a/uninstall.sh b/uninstall.sh
new file mode 100644
index 0000000..a1acbbf
--- /dev/null
+++ b/uninstall.sh
@@ -0,0 +1,10 @@
+#!/bin/sh -e
+
+script_dir=$(dirname "$0")
+cd "$script_dir"
+
+[ $(id -u) -ne 0 ] && echo "You need root privileges to run the uninstall script" && exit 1
+
+ninja -C build uninstall
+
+echo "Successfully uninstalled quickmedia" \ No newline at end of file
diff --git a/video_player/jsoncpp b/video_player/jsoncpp
-Subproject f23fb32fd9d9c3d01fa67afa0d75f7ff227647e
+Subproject 98e28b38ffbae24c0e69e620bf18f8a0c5c6f20