Skip to content

Commit 305145a

Browse files
suenotclaude
andcommitted
feat: new chat creation, interface scaling, notification settings (v0.7.0)
- Add create group, channel, supergroup commands (Rust backend) - Add NewChatButton with dropdown menu in sidebar - Add interface scale slider (50%-200%) with live zoom - Add message text size selector (small/medium/large) - Wire notification sound & message preview toggles to settings store - Add markdown rendering in merged message groups - i18n for all new features (en/ru) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent db64ae5 commit 305145a

20 files changed

Lines changed: 1439 additions & 19 deletions

File tree

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Changelog
22

3+
## [0.7.0] - 2026-03-15
4+
### Features
5+
- Create group chats, channels, and supergroups from sidebar
6+
- New Chat button with dropdown menu (group, channel, secret chat)
7+
- Interface scale slider (50%–200%) with live zoom
8+
- Message text size selector (small / medium / large)
9+
- Notification sound toggle (silent notifications)
10+
- Message preview toggle (hide text in notifications)
11+
- Markdown rendering in merged message groups
12+
13+
### Improvements
14+
- Settings controls fully wired to persistent store
15+
- i18n translations for all new features (en/ru)
16+
317
## [0.6.0] - 2026-03-15
418
### Features
519
- Voice & video calls with E2E encryption (DH key exchange)

docs/changelog/v0.7.0.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# v0.7.0 - 2026-03-15
2+
3+
## Features
4+
- **Create Group**: new Tauri command to create basic groups with selected contacts
5+
- **Create Channel**: new Tauri command to create channels/supergroups
6+
- **Get Contacts**: new Tauri command to fetch user-type chats as contacts
7+
- **New Chat Button**: sidebar button with dropdown menu to create groups, channels, and secret chats
8+
- **Interface Scale**: working slider (50%–200%) with live zoom applied via CSS
9+
- **Message Text Size**: radio selector (small / medium / large) with CSS custom property
10+
- **Notification Sound**: toggle to send silent/audible OS notifications
11+
- **Message Preview**: toggle to hide message text in notifications
12+
- **Markdown in merged messages**: merged message groups now render markdown when enabled
13+
14+
## Improvements
15+
- Settings controls are now fully wired to the settings store (previously some were static/default)
16+
- i18n translations added for all new features (en/ru)
17+
18+
## Affected Files
19+
- `src-tauri/src/commands/chats.rs` — create_group, create_channel, get_contacts
20+
- `src-tauri/src/lib.rs` — registered new commands
21+
- `src/components/Chat/NewChatButton.tsx` — new component
22+
- `src/components/Chat/NewChatDialog.css` — new styles
23+
- `src/components/Layout/MainLayout.tsx` — integrated NewChatButton
24+
- `src/components/Layout/MainLayout.css` — new-chat-menu styles
25+
- `src/components/Messages/MessageList.tsx` — markdown in merged messages
26+
- `src/components/Messages/MessageList.css` — message font-size variable
27+
- `src/components/Settings/AccountSettings.tsx` — scale slider, text size, notification toggles
28+
- `src/store/settingsStore.ts` — new settings fields
29+
- `src/hooks/useNotifications.ts` — sound & preview toggles
30+
- `src/App.tsx` — apply interface scale & message text size
31+
- `src/i18n/locales/en.ts`, `ru.ts` — translations

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "vasyapp",
33
"private": true,
4-
"version": "0.6.0",
4+
"version": "0.7.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "telegram-client"
3-
version = "0.6.0"
3+
version = "0.7.0"
44
description = "A Tauri App"
55
authors = ["you"]
66
edition = "2021"

src-tauri/src/commands/chats.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,167 @@ pub async fn delete_and_leave_chat(
371371
Ok(())
372372
}
373373

374+
/// Create a new group chat (basic group)
375+
#[tauri::command]
376+
pub async fn create_group(
377+
account_id: String,
378+
title: String,
379+
user_ids: Vec<i64>,
380+
state: State<'_, Arc<RwLock<AppState>>>,
381+
) -> Result<i64, String> {
382+
tracing::info!(account_id = %account_id, title = %title, "Creating group");
383+
384+
let wrapper = {
385+
let state_guard = state.read().await;
386+
let client_manager = state_guard
387+
.client_manager
388+
.as_ref()
389+
.ok_or("Client manager not initialized")?;
390+
client_manager
391+
.get_client(&account_id)
392+
.await
393+
.ok_or("Client not found for this account")?
394+
};
395+
396+
// Resolve user_ids to InputUser
397+
let mut input_users = Vec::new();
398+
for uid in &user_ids {
399+
let peer = super::peer_resolve::resolve_peer(&wrapper, *uid).await?;
400+
let peer_ref = PeerRef::from(&peer);
401+
let input_user: tl::enums::InputUser = peer_ref.into();
402+
input_users.push(input_user);
403+
}
404+
405+
let request = tl::functions::messages::CreateChat {
406+
users: input_users,
407+
title,
408+
ttl_period: None,
409+
};
410+
411+
let result = wrapper.client.invoke(&request)
412+
.await
413+
.map_err(|e| format!("Failed to create group: {}", e))?;
414+
415+
// Extract chat ID from InvitedUsers result
416+
let chat_id = match &result {
417+
tl::enums::messages::InvitedUsers::Users(invited) => {
418+
// The updates contain the new chat info
419+
match &invited.updates {
420+
tl::enums::Updates::Updates(u) => {
421+
// Find the chat in the chats list
422+
u.chats.first().map(|c| match c {
423+
tl::enums::Chat::Chat(chat) => -(chat.id as i64), // Bot API format for groups
424+
tl::enums::Chat::Channel(ch) => {
425+
let id = ch.id as i64;
426+
-1_000_000_000_000 - id // Bot API format for channels/supergroups
427+
}
428+
_ => 0,
429+
}).unwrap_or(0)
430+
}
431+
_ => 0,
432+
}
433+
}
434+
};
435+
436+
tracing::info!(account_id = %account_id, chat_id = chat_id, "Group created successfully");
437+
Ok(chat_id)
438+
}
439+
440+
/// Create a new channel or supergroup (megagroup)
441+
#[tauri::command]
442+
pub async fn create_channel(
443+
account_id: String,
444+
title: String,
445+
about: String,
446+
is_megagroup: bool,
447+
state: State<'_, Arc<RwLock<AppState>>>,
448+
) -> Result<i64, String> {
449+
tracing::info!(account_id = %account_id, title = %title, is_megagroup = is_megagroup, "Creating channel");
450+
451+
let wrapper = {
452+
let state_guard = state.read().await;
453+
let client_manager = state_guard
454+
.client_manager
455+
.as_ref()
456+
.ok_or("Client manager not initialized")?;
457+
client_manager
458+
.get_client(&account_id)
459+
.await
460+
.ok_or("Client not found for this account")?
461+
};
462+
463+
let request = tl::functions::channels::CreateChannel {
464+
broadcast: !is_megagroup,
465+
megagroup: is_megagroup,
466+
for_import: false,
467+
forum: false,
468+
title,
469+
about,
470+
geo_point: None,
471+
address: None,
472+
ttl_period: None,
473+
};
474+
475+
let result = wrapper.client.invoke(&request)
476+
.await
477+
.map_err(|e| format!("Failed to create channel: {}", e))?;
478+
479+
// Extract channel ID from Updates
480+
let chat_id = match &result {
481+
tl::enums::Updates::Updates(u) => {
482+
u.chats.first().map(|c| match c {
483+
tl::enums::Chat::Channel(ch) => {
484+
let id = ch.id as i64;
485+
-1_000_000_000_000 - id
486+
}
487+
_ => 0,
488+
}).unwrap_or(0)
489+
}
490+
_ => 0,
491+
};
492+
493+
tracing::info!(account_id = %account_id, chat_id = chat_id, "Channel created successfully");
494+
Ok(chat_id)
495+
}
496+
497+
/// Get contacts (users from chat list)
498+
#[tauri::command]
499+
pub async fn get_contacts(
500+
account_id: String,
501+
state: State<'_, Arc<RwLock<AppState>>>,
502+
) -> Result<Vec<Chat>, String> {
503+
let state_guard = state.read().await;
504+
let storage = Arc::clone(
505+
state_guard
506+
.storage
507+
.as_ref()
508+
.ok_or("Storage not initialized")?,
509+
);
510+
drop(state_guard);
511+
512+
let records = storage.get_chats(&account_id).await
513+
.map_err(|e| format!("Failed to get chats from storage: {}", e))?;
514+
515+
// Filter to only user-type chats (contacts)
516+
let contacts = records
517+
.into_iter()
518+
.filter(|r| r.chat_type == "user")
519+
.map(|r| Chat {
520+
id: r.id,
521+
title: r.title,
522+
username: r.username,
523+
unread_count: r.unread_count,
524+
chat_type: r.chat_type,
525+
last_message: r.last_message,
526+
avatar_path: r.avatar_path,
527+
is_forum: r.is_forum,
528+
is_muted: false,
529+
})
530+
.collect();
531+
532+
Ok(contacts)
533+
}
534+
374535
/// Helper function to download avatar for a peer.
375536
/// The `avatars_dir` must be an absolute path (derived from app_data_dir).
376537
/// Uses a semaphore to limit concurrent downloads and handles FLOOD_WAIT.

src-tauri/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ pub fn run() {
7575
commands::search_messages,
7676
commands::get_my_avatar,
7777
commands::delete_and_leave_chat,
78+
commands::create_group,
79+
commands::create_channel,
80+
commands::get_contacts,
7881
commands::get_stt_settings,
7982
commands::set_stt_settings,
8083
commands::transcribe_audio,

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "Vasyapp",
4-
"version": "0.6.0",
4+
"version": "0.7.0",
55
"identifier": "com.suenot.vasyapp",
66
"build": {
77
"beforeDevCommand": "npm run dev",

src/App.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ function App() {
7575
}
7676
}, [setConnected, setDisconnected, setReconnecting]));
7777

78+
// Apply interface scale
79+
const interfaceScale = useSettingsStore((s) => s.interfaceScale);
80+
useEffect(() => {
81+
document.documentElement.style.zoom = `${interfaceScale / 100}`;
82+
}, [interfaceScale]);
83+
84+
// Apply message text size
85+
const messageTextSize = useSettingsStore((s) => s.messageTextSize);
86+
useEffect(() => {
87+
const sizes = { small: '13px', medium: '14.5px', large: '16px' };
88+
document.documentElement.style.setProperty('--message-font-size', sizes[messageTextSize]);
89+
}, [messageTextSize]);
90+
7891
// Применяем тему при монтировании и изменении настроек
7992
useEffect(() => {
8093
const effectiveTheme = themeSetting === 'system' ? systemTheme : themeSetting;

0 commit comments

Comments
 (0)