feat: implement photo albums (media groups) and persist account selection

Group photos with shared media_album_id into single album bubbles with
grid layout (up to 3x cols). Album navigation treats grouped photos as
one unit (j/k skip entire album). Persist selected account to
accounts.toml so it survives app restart.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mikhail Kilin
2026-02-22 16:18:04 +03:00
parent 8bd08318bb
commit 78fe09bf11
18 changed files with 1011 additions and 30 deletions

View File

@@ -387,3 +387,118 @@ fn snapshot_selected_message() {
let output = buffer_to_string(&buffer);
assert_snapshot!("selected_message", output);
}
#[test]
fn snapshot_album_incoming() {
let chat = create_test_chat("Mom", 123);
let msg1 = TestMessageBuilder::new("📷 [Фото]", 1)
.sender("Alice")
.media_album_id(12345)
.build();
let msg2 = TestMessageBuilder::new("Caption for album", 2)
.sender("Alice")
.media_album_id(12345)
.build();
let msg3 = TestMessageBuilder::new("📷 [Фото]", 3)
.sender("Alice")
.media_album_id(12345)
.build();
let mut app = TestAppBuilder::new()
.with_chat(chat)
.with_messages(123, vec![msg1, msg2, msg3])
.selected_chat(123)
.build();
let buffer = render_to_buffer(80, 24, |f| {
tele_tui::ui::messages::render(f, f.area(), &mut app);
});
let output = buffer_to_string(&buffer);
assert_snapshot!("album_incoming", output);
}
#[test]
fn snapshot_album_outgoing() {
let chat = create_test_chat("Mom", 123);
let msg1 = TestMessageBuilder::new("📷 [Фото]", 1)
.outgoing()
.media_album_id(99999)
.build();
let msg2 = TestMessageBuilder::new("My vacation photos", 2)
.outgoing()
.media_album_id(99999)
.build();
let mut app = TestAppBuilder::new()
.with_chat(chat)
.with_messages(123, vec![msg1, msg2])
.selected_chat(123)
.build();
let buffer = render_to_buffer(80, 24, |f| {
tele_tui::ui::messages::render(f, f.area(), &mut app);
});
let output = buffer_to_string(&buffer);
assert_snapshot!("album_outgoing", output);
}
#[test]
fn snapshot_album_with_regular_messages() {
let chat = create_test_chat("Group Chat", 123);
let msg1 = TestMessageBuilder::new("Regular message before", 1)
.sender("Alice")
.build();
let msg2 = TestMessageBuilder::new("📷 [Фото]", 2)
.sender("Alice")
.media_album_id(555)
.build();
let msg3 = TestMessageBuilder::new("Album caption", 3)
.sender("Alice")
.media_album_id(555)
.build();
let msg4 = TestMessageBuilder::new("Regular message after", 4)
.sender("Alice")
.build();
let mut app = TestAppBuilder::new()
.with_chat(chat)
.with_messages(123, vec![msg1, msg2, msg3, msg4])
.selected_chat(123)
.build();
let buffer = render_to_buffer(80, 24, |f| {
tele_tui::ui::messages::render(f, f.area(), &mut app);
});
let output = buffer_to_string(&buffer);
assert_snapshot!("album_with_regular_messages", output);
}
#[test]
fn snapshot_album_selected() {
let chat = create_test_chat("Mom", 123);
let msg1 = TestMessageBuilder::new("📷 [Фото]", 1)
.sender("Alice")
.media_album_id(777)
.build();
let msg2 = TestMessageBuilder::new("📷 [Фото]", 2)
.sender("Alice")
.media_album_id(777)
.build();
let mut app = TestAppBuilder::new()
.with_chat(chat)
.with_messages(123, vec![msg1, msg2])
.selected_chat(123)
.selecting_message(1) // Выбираем одно из сообщений альбома
.build();
let buffer = render_to_buffer(80, 24, |f| {
tele_tui::ui::messages::render(f, f.area(), &mut app);
});
let output = buffer_to_string(&buffer);
assert_snapshot!("album_selected", output);
}