Skip to content

Commit

Permalink
Image previews
Browse files Browse the repository at this point in the history
Additionally to enable the preview feature, one must add it to
config.json:
```json
    "image_preview": {}
```
See documentation for additional settings - they shouldn't be necessary
in most cases.

A feature flag for sixel support is added.

Windows is basically unsupported, but it is possible to force the
feature, if the `protocol` option is set with `type` and `font_size`.
  • Loading branch information
benjajaja committed Oct 23, 2023
1 parent 8943909 commit 2861155
Show file tree
Hide file tree
Showing 15 changed files with 533 additions and 27 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ jobs:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: 'github-check'
- name: Run tests
run: cargo test
run: cargo test ${{ matrix.platform == 'windows-latest' && '--no-default-features' || '' }}
- name: Build artifacts
run: cargo build --release
run: cargo build --release ${{ matrix.platform == 'windows-latest' && '--no-default-features' || '' }}
- name: Upload artifacts
uses: actions/upload-artifact@master
with:
Expand Down
48 changes: 48 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ markup5ever_rcdom = "0.2.0"
mime = "^0.3.16"
mime_guess = "^2.0.4"
open = "3.2.0"
ratatui-image = { version = "0.3.3", features = ["serde", "rustix"] }
regex = "^1.5"
rpassword = "^7.2"
serde = "^1.0"
Expand Down Expand Up @@ -74,3 +75,7 @@ pretty_assertions = "1.4.0"
[profile.release]
lto = true
incremental = false

[features]
default = ["sixel"]
sixel = ["ratatui-image/sixel"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ two other TUI clients and Element Web:
| Room upgrades | ❌ ([#41]) | ✔️ || ✔️ |
| Localisations || 1 || 44 |
| SSO Support || ✔️ | ✔️ | ✔️ |
| Image preview | ✔️ ||| ✔️ |
## License

Expand Down
11 changes: 10 additions & 1 deletion docs/example_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@
"color": "magenta"
}
},
"default_room": "#iamb-users:0x.badd.cafe"
"default_room": "#iamb-users:0x.badd.cafe",
"image_preview": {
"protocol": {
"type": "sixel"
},
"size": {
"width": 66,
"height": 10
}
}
},
"dirs": {
"cache": "/home/user/.cache/iamb/",
Expand Down
15 changes: 15 additions & 0 deletions docs/iamb.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ overridden as described in *PROFILES*.
**default_room** (type: string)
> The room to show by default instead of a welcome-screen.
**image_preview** (type: image_preview object)
> Enable image previews and configure it. An empty object will enable the
> feature with default settings, omitting it will disable the feature.
> *size* is an optional object with *width* and *height* numbers, which are
> used te set the preview size in characters. Defaults to 66 and 10.
> *protocol* is an optional object to override settings that should normally
> be guessed automatically.
> *protocol.type* is an optional string with one of the protocol types:
> _sixel_, _kitty_, _halfblocks_.
> *protocol.font_size* is an optional list of two numbers representing font
> width and height in pixels.
## USER OVERRIDES

Overrides are mapped onto matrix User IDs such as _@user:matrix.org_ and are
Expand Down Expand Up @@ -127,6 +139,9 @@ Specifies the directories to save data in. Configured as a map under the key
**downloads** (type: string)
> Specifies where to store downloaded files.
**image_previews** (type: string)
> Specifies where to store automatically downloaded image previews.
# SEE ALSO

*iamb(1)*
Expand Down
15 changes: 11 additions & 4 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,25 @@
pname = "iamb";
version = "0.0.7";
src = ./.;
cargoLock.lockFile = ./Cargo.lock;
cargoLock = {
lockFile = ./Cargo.lock;
# Remove this once modalkit gets pinned by version again.
outputHashes = {
"modalkit-0.0.16" = "sha256-mjAD1v0r2+SzPdoB2wZ/5iJ1NZK+3OSvCYcUZ5Ef38Y=";
};
};
nativeBuildInputs = [ pkgs.pkgconfig ];
buildInputs = [ pkgs.openssl ] ++ pkgs.lib.optionals pkgs.stdenv.isDarwin
(with pkgs.darwin.apple_sdk.frameworks; [ AppKit Security ]);
};
devShell = mkShell {
buildInputs = [
(rustNightly.override { extensions = [ "rust-src" ]; })
(rustNightly.override {
extensions = [ "rust-src" "rust-analyzer-preview" "rustfmt" "clippy" ];
})
pkg-config
cargo-tarpaulin
rust-analyzer
rustfmt
cargo-watch
];
};
});
Expand Down
50 changes: 49 additions & 1 deletion src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::sync::Arc;
use std::time::{Duration, Instant};

use emojis::Emoji;
use ratatui_image::picker::Picker;
use serde::{
de::Error as SerdeError,
de::Visitor,
Expand Down Expand Up @@ -81,6 +82,8 @@ use modalkit::{
},
};

use crate::message::ImageStatus;
use crate::preview::{source_from_event, spawn_insert_preview};
use crate::{
message::{Message, MessageEvent, MessageKey, MessageTimeStamp, Messages},
worker::Requester,
Expand Down Expand Up @@ -617,6 +620,12 @@ pub enum IambError {
/// A failure to access the system's clipboard.
#[error("Could not use system clipboard data")]
Clipboard,

#[error("IO error: {0}")]
IOError(#[from] std::io::Error),

#[error("Preview error: {0}")]
Preview(String),
}

impl From<IambError> for UIError<IambInfo> {
Expand Down Expand Up @@ -737,6 +746,11 @@ impl RoomInfo {
self.messages.get(self.get_message_key(event_id)?)
}

/// Get an event for an identifier as mutable.
pub fn get_event_mut(&mut self, event_id: &EventId) -> Option<&mut Message> {
self.messages.get_mut(self.keys.get(event_id)?.to_message_key()?)
}

/// Insert a reaction to a message.
pub fn insert_reaction(&mut self, react: ReactionEvent) {
match react {
Expand Down Expand Up @@ -827,6 +841,37 @@ impl RoomInfo {
}
}

/// Insert a new message event, and spawn a task for image-preview if it has an image
/// attachment.
pub fn insert_with_preview(
&mut self,
room_id: OwnedRoomId,
store: AsyncProgramStore,
picker: Option<Picker>,
ev: RoomMessageEvent,
settings: &mut ApplicationSettings,
media: matrix_sdk::Media,
) {
let source = picker.and_then(|_| source_from_event(&ev));
self.insert(ev);

if let Some((event_id, source)) = source {
if let (Some(msg), Some(image_preview)) =
(self.get_event_mut(&event_id), &settings.tunables.image_preview)
{
msg.image_preview = ImageStatus::Downloading(image_preview.size.clone());
spawn_insert_preview(
store,
room_id,
event_id,
source,
media,
settings.dirs.image_previews.clone(),
)
}
}
}

/// Indicates whether we've recently fetched scrollback for this room.
pub fn recently_fetched(&self) -> bool {
self.fetch_last.map_or(false, |i| i.elapsed() < ROOM_FETCH_DEBOUNCE)
Expand Down Expand Up @@ -980,6 +1025,9 @@ pub struct ChatStore {

/// Information gathered by the background thread.
pub sync_info: SyncInfo,

/// Image preview "protocol" picker.
pub picker: Option<Picker>,
}

impl ChatStore {
Expand All @@ -988,7 +1036,7 @@ impl ChatStore {
ChatStore {
worker,
settings,

picker: None,
cmds: crate::commands::setup_commands(),
emojis: emoji_map(),

Expand Down

0 comments on commit 2861155

Please sign in to comment.