mirror of https://github.com/CympleTech/ESSE.git
35 changed files with 967 additions and 586 deletions
@ -0,0 +1,122 @@
@@ -0,0 +1,122 @@
|
||||
import 'package:flutter/material.dart'; |
||||
|
||||
import 'package:esse/l10n/localizations.dart'; |
||||
import 'package:esse/utils/relative_time.dart'; |
||||
import 'package:esse/widgets/avatar.dart'; |
||||
import 'package:esse/global.dart'; |
||||
import 'package:esse/apps/service/models.dart'; |
||||
import 'package:esse/apps/primitives.dart'; |
||||
|
||||
enum SessionType { |
||||
Chat, |
||||
Group, |
||||
Files, |
||||
Device, |
||||
Assistant, |
||||
Domain, |
||||
Service, |
||||
} |
||||
|
||||
extension SessionTypeExtension on SessionType { |
||||
static SessionType fromInt(int s) { |
||||
switch (s) { |
||||
case 0: |
||||
return SessionType.Chat; |
||||
case 1: |
||||
return SessionType.Group; |
||||
case 2: |
||||
return SessionType.Files; |
||||
case 3: |
||||
return SessionType.Device; |
||||
case 4: |
||||
return SessionType.Assistant; |
||||
case 5: |
||||
return SessionType.Domain; |
||||
case 6: |
||||
return SessionType.Service; |
||||
default: |
||||
return SessionType.Chat; |
||||
} |
||||
} |
||||
} |
||||
|
||||
class Session { |
||||
int id; |
||||
int fid; |
||||
String gid; |
||||
String addr; |
||||
SessionType type; |
||||
String name; |
||||
bool isTop; |
||||
RelativeTime lastTime; |
||||
String lastContent; |
||||
bool lastReaded; |
||||
bool online = false; |
||||
|
||||
static List innerService(InnerService service, AppLocalizations lang) { |
||||
final params = service.params(lang); |
||||
final avatar = Container( |
||||
padding: const EdgeInsets.all(6.0), |
||||
decoration: BoxDecoration( |
||||
borderRadius: BorderRadius.circular(15.0), |
||||
), |
||||
child: Image.asset(params[2]), |
||||
); |
||||
final name = params[0]; |
||||
final bio = params[1]; |
||||
|
||||
return [avatar, name, bio]; |
||||
} |
||||
|
||||
List parse(AppLocalizations lang) { |
||||
switch (this.type) { |
||||
case SessionType.Chat: |
||||
return [showAvatar(), this.name, this.lastContent, this.lastTime.toString()]; |
||||
case SessionType.Assistant: |
||||
final params = Session.innerService(InnerService.Assistant, lang); |
||||
return [params[0], params[1], params[2], '']; |
||||
case SessionType.Files: |
||||
final params = Session.innerService(InnerService.Files, lang); |
||||
return [params[0], params[1], params[2], '']; |
||||
} |
||||
} |
||||
|
||||
Avatar showAvatar({double width = 45.0, bool needOnline = true}) { |
||||
final avatar = Global.avatarPath + this.gid + '.png'; |
||||
return Avatar( |
||||
width: width, |
||||
name: this.name, |
||||
avatarPath: avatar, |
||||
online: this.online, |
||||
needOnline: needOnline, |
||||
hasNew: !this.lastReaded, |
||||
); |
||||
} |
||||
|
||||
last(List params) { |
||||
this.lastTime = RelativeTime.fromInt(params[1]); |
||||
this.lastContent = params[2]; |
||||
this.lastReaded = params[3]; |
||||
} |
||||
|
||||
update(List params) { |
||||
this.addr = params[1]; |
||||
this.name = params[2]; |
||||
this.isTop = params[3]; |
||||
this.online = params[4]; |
||||
} |
||||
|
||||
Session.fromList(List params) { |
||||
this.id = params[0]; |
||||
this.fid = params[1]; |
||||
this.gid = params[2]; |
||||
this.addr = params[3]; |
||||
this.type = SessionTypeExtension.fromInt(params[4]); |
||||
this.name = params[5]; |
||||
this.isTop = params[6]; |
||||
this.lastTime = RelativeTime.fromInt(params[7]); |
||||
this.lastContent = params[8]; |
||||
this.lastReaded = params[9]; |
||||
this.online = params[10]; |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
#[rustfmt::skip] |
||||
pub(super) const CHAT_VERSIONS: [&str; 3] = [ |
||||
"CREATE TABLE IF NOT EXISTS friends( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
gid TEXT NOT NULL, |
||||
addr TEXT NOT NULL, |
||||
name TEXT NOT NULL, |
||||
remark TEXT, |
||||
is_closed INTEGER NOT NULL, |
||||
datetime INTEGER NOT NULL, |
||||
is_deleted INTEGER NOT NULL);", |
||||
"CREATE TABLE IF NOT EXISTS requests( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
gid TEXT NOT NULL, |
||||
addr TEXT NOT NULL, |
||||
name TEXT, |
||||
remark TEXT, |
||||
is_me INTEGER NOT NULL, |
||||
is_ok INTEGER NOT NULL, |
||||
is_over INTEGER NOT NULL, |
||||
is_delivery INTEGER NOT NULL, |
||||
datetime INTEGER NOT NULL, |
||||
is_deleted INTEGER NOT NULL);", |
||||
"CREATE TABLE IF NOT EXISTS messages( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
hash TEXT NOT NULL, |
||||
fid INTEGER NOT NULL, |
||||
is_me INTEGER NOT NULL, |
||||
m_type INTEGER NOT NULL, |
||||
content TEXT NOT NULL, |
||||
is_delivery INTEGER NOT NULL, |
||||
datetime INTEGER NOT NULL, |
||||
is_deleted INTEGER NOT NULL);", |
||||
]; |
@ -1,37 +1,16 @@
@@ -1,37 +1,16 @@
|
||||
#[rustfmt::skip] |
||||
pub(super) const SESSION_VERSIONS: [&str; 3] = [ |
||||
"CREATE TABLE IF NOT EXISTS friends( |
||||
"CREATE TABLE IF NOT EXISTS sessions( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
fid INTEGER NOT NULL, |
||||
gid TEXT NOT NULL, |
||||
addr TEXT NOT NULL, |
||||
s_type INTEGER NOT NULL, |
||||
name TEXT NOT NULL, |
||||
remark TEXT, |
||||
is_top INTEGER NOT NULL, |
||||
is_closed INTEGER NOT NULL, |
||||
last_message_datetime INTEGER, |
||||
last_message_content TEXT, |
||||
last_message_readed INTEGER, |
||||
is_deleted INTEGER NOT NULL);", |
||||
"CREATE TABLE IF NOT EXISTS requests( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
gid TEXT NOT NULL, |
||||
addr TEXT NOT NULL, |
||||
name TEXT, |
||||
remark TEXT, |
||||
is_me INTEGER NOT NULL, |
||||
is_ok INTEGER NOT NULL, |
||||
is_over INTEGER NOT NULL, |
||||
is_delivery INTEGER NOT NULL, |
||||
datetime INTEGER NOT NULL, |
||||
is_deleted INTEGER NOT NULL);", |
||||
"CREATE TABLE IF NOT EXISTS messages( |
||||
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, |
||||
hash TEXT NOT NULL, |
||||
fid INTEGER NOT NULL, |
||||
is_me INTEGER NOT NULL, |
||||
m_type INTEGER NOT NULL, |
||||
content TEXT NOT NULL, |
||||
is_delivery INTEGER NOT NULL, |
||||
datetime INTEGER NOT NULL, |
||||
is_deleted INTEGER NOT NULL);", |
||||
last_datetime INTEGER, |
||||
last_content TEXT, |
||||
last_readed INTEGER);", |
||||
"INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, last_datetime, last_content, last_readed) VALUES (0, '', '', 4, '', 0, 0, '', 1);", // Assistant.
|
||||
"INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, last_datetime, last_content, last_readed) VALUES (0, '', '', 2, '', 0, 0, '', 1);", // File.
|
||||
]; |
||||
|
@ -0,0 +1,171 @@
@@ -0,0 +1,171 @@
|
||||
use tdn::types::{ |
||||
group::GroupId, |
||||
primitive::{new_io_error, PeerAddr, Result}, |
||||
rpc::{json, RpcParam}, |
||||
}; |
||||
use tdn_storage::local::{DStorage, DsValue}; |
||||
|
||||
pub(crate) enum SessionType { |
||||
Chat, |
||||
Group, |
||||
Files, |
||||
Device, |
||||
Assistant, |
||||
Domain, |
||||
Service, |
||||
} |
||||
|
||||
impl SessionType { |
||||
fn to_int(&self) -> i64 { |
||||
match self { |
||||
SessionType::Chat => 0, |
||||
SessionType::Group => 1, |
||||
SessionType::Files => 2, |
||||
SessionType::Device => 3, |
||||
SessionType::Assistant => 4, |
||||
SessionType::Domain => 5, |
||||
SessionType::Service => 6, |
||||
} |
||||
} |
||||
|
||||
fn from_int(i: i64) -> Self { |
||||
match i { |
||||
0 => SessionType::Chat, |
||||
1 => SessionType::Group, |
||||
2 => SessionType::Files, |
||||
3 => SessionType::Device, |
||||
4 => SessionType::Assistant, |
||||
5 => SessionType::Domain, |
||||
6 => SessionType::Service, |
||||
_ => SessionType::Chat, |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub(crate) struct Session { |
||||
id: i64, |
||||
fid: i64, |
||||
pub gid: GroupId, |
||||
pub addr: PeerAddr, |
||||
pub s_type: SessionType, |
||||
name: String, |
||||
is_top: bool, |
||||
last_datetime: i64, |
||||
last_content: String, |
||||
last_readed: bool, |
||||
pub online: bool, |
||||
} |
||||
|
||||
impl Session { |
||||
pub fn new( |
||||
fid: i64, |
||||
gid: GroupId, |
||||
addr: PeerAddr, |
||||
s_type: SessionType, |
||||
name: String, |
||||
datetime: i64, |
||||
) -> Self { |
||||
Self { |
||||
fid, |
||||
gid, |
||||
addr, |
||||
s_type, |
||||
name, |
||||
id: 0, |
||||
is_top: false, |
||||
last_datetime: datetime, |
||||
last_content: "".to_owned(), |
||||
last_readed: true, |
||||
online: false, |
||||
} |
||||
} |
||||
|
||||
pub fn to_rpc(&self) -> RpcParam { |
||||
json!([ |
||||
self.id, |
||||
self.fid, |
||||
self.gid.to_hex(), |
||||
self.addr.to_hex(), |
||||
self.s_type.to_int(), |
||||
self.name, |
||||
self.is_top, |
||||
self.last_datetime, |
||||
self.last_content, |
||||
self.last_readed, |
||||
self.online |
||||
]) |
||||
} |
||||
|
||||
fn from_values(mut v: Vec<DsValue>) -> Self { |
||||
Self { |
||||
last_readed: v.pop().unwrap().as_bool(), |
||||
last_content: v.pop().unwrap().as_string(), |
||||
last_datetime: v.pop().unwrap().as_i64(), |
||||
is_top: v.pop().unwrap().as_bool(), |
||||
name: v.pop().unwrap().as_string(), |
||||
s_type: SessionType::from_int(v.pop().unwrap().as_i64()), |
||||
addr: PeerAddr::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerAddr::default()), |
||||
gid: GroupId::from_hex(v.pop().unwrap().as_str()).unwrap_or(GroupId::default()), |
||||
fid: v.pop().unwrap().as_i64(), |
||||
id: v.pop().unwrap().as_i64(), |
||||
online: false, |
||||
} |
||||
} |
||||
|
||||
pub fn insert(&mut self, db: &DStorage) -> Result<()> { |
||||
let sql = format!("INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, last_datetime, last_content, last_readed) VALUES ({}, '{}', '{}', {}, '{}', {}, {}, '{}', {})", |
||||
self.fid, |
||||
self.gid.to_hex(), |
||||
self.addr.to_hex(), |
||||
self.s_type.to_int(), |
||||
self.name, |
||||
if self.is_top { 1 } else { 0 }, |
||||
self.last_datetime, |
||||
self.last_content, |
||||
if self.last_readed { 1 } else { 0 }, |
||||
); |
||||
let id = db.insert(&sql)?; |
||||
self.id = id; |
||||
Ok(()) |
||||
} |
||||
|
||||
pub fn get(db: &DStorage, id: i64) -> Result<Session> { |
||||
let sql = format!("SELECT id, fid, gid, addr, s_type, name, is_top, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id); |
||||
let mut matrix = db.query(&sql)?; |
||||
if matrix.len() > 0 { |
||||
Ok(Session::from_values(matrix.pop().unwrap())) // safe unwrap()
|
||||
} else { |
||||
Err(new_io_error("session missing.")) |
||||
} |
||||
} |
||||
|
||||
pub fn list(db: &DStorage) -> Result<Vec<Session>> { |
||||
let matrix = db.query("SELECT id, fid, gid, addr, s_type, name, is_top, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?; |
||||
let mut sessions = vec![]; |
||||
for values in matrix { |
||||
sessions.push(Session::from_values(values)); |
||||
} |
||||
Ok(sessions) |
||||
} |
||||
|
||||
pub fn top(db: &DStorage, id: &i64, is_top: bool) -> Result<usize> { |
||||
db.update(&format!("UPDATE sessions SET is_top = 1 WHERE id = {}", id)) |
||||
} |
||||
|
||||
pub fn last( |
||||
db: &DStorage, |
||||
id: &i64, |
||||
datetime: &i64, |
||||
content: &str, |
||||
readed: bool, |
||||
) -> Result<usize> { |
||||
db.update(&format!("UPDATE sessions SET last_datetime = {}, last_content = '{}', last_readed = {} WHERE id = {}", datetime, content, if readed { 1 } else { 0 }, id)) |
||||
} |
||||
|
||||
pub fn read(db: &DStorage, id: &i64) -> Result<usize> { |
||||
db.update(&format!( |
||||
"UPDATE sessions SET last_readed = 1 WHERE id = {}", |
||||
id |
||||
)) |
||||
} |
||||
} |
Loading…
Reference in new issue