2022-12-11 16:40:35 +03:00
import ' package:flutter/widgets.dart ' ;
import ' package:flutter_hbb/common.dart ' ;
import ' package:flutter_hbb/common/hbbs/hbbs.dart ' ;
2023-09-14 05:17:03 +03:00
import ' package:flutter_hbb/common/widgets/peers_view.dart ' ;
2022-12-11 16:40:35 +03:00
import ' package:flutter_hbb/models/model.dart ' ;
import ' package:flutter_hbb/models/peer_model.dart ' ;
import ' package:flutter_hbb/models/platform_model.dart ' ;
import ' package:get/get.dart ' ;
import ' dart:convert ' ;
2024-04-25 06:46:21 +03:00
import ' ../utils/http_service.dart ' as http ;
2022-12-11 16:40:35 +03:00
class GroupModel {
2023-06-17 15:48:58 +03:00
final RxBool groupLoading = false . obs ;
final RxString groupLoadError = " " . obs ;
2022-12-11 16:40:35 +03:00
final RxList < UserPayload > users = RxList . empty ( growable: true ) ;
2023-09-14 05:17:03 +03:00
final RxList < Peer > peers = RxList . empty ( growable: true ) ;
2023-06-21 04:30:32 +03:00
final RxString selectedUser = ' ' . obs ;
final RxString searchUserText = ' ' . obs ;
2022-12-11 16:40:35 +03:00
WeakReference < FFI > parent ;
2023-06-23 10:10:10 +03:00
var initialized = false ;
2023-09-14 05:17:03 +03:00
var _cacheLoadOnceFlag = false ;
var _statusCode = 200 ;
2022-12-11 16:40:35 +03:00
2023-09-14 05:17:03 +03:00
bool get emtpy = > users . isEmpty & & peers . isEmpty ;
2022-12-11 16:40:35 +03:00
2023-09-14 05:17:03 +03:00
GroupModel ( this . parent ) ;
2022-12-11 16:40:35 +03:00
2023-06-23 12:05:48 +03:00
Future < void > pull ( { force = true , quiet = false } ) async {
2024-05-28 15:10:12 +03:00
if ( bind . isDisableGroupPanel ( ) ) return ;
2023-09-14 05:17:03 +03:00
if ( ! gFFI . userModel . isLogin | | groupLoading . value ) return ;
2024-07-28 05:15:09 +03:00
if ( gFFI . userModel . networkError . isNotEmpty ) return ;
2023-06-23 10:10:10 +03:00
if ( ! force & & initialized ) return ;
2023-06-23 12:05:48 +03:00
if ( ! quiet ) {
groupLoading . value = true ;
groupLoadError . value = " " ;
}
2023-09-14 05:17:03 +03:00
try {
await _pull ( ) ;
} catch ( _ ) { }
2023-06-21 11:04:52 +03:00
groupLoading . value = false ;
2023-06-23 10:10:10 +03:00
initialized = true ;
2023-09-14 05:17:03 +03:00
platformFFI . tryHandle ( { ' name ' : LoadEvent . group } ) ;
if ( _statusCode = = 401 ) {
gFFI . userModel . reset ( resetOther: true ) ;
} else {
_saveCache ( ) ;
}
2023-06-21 11:04:52 +03:00
}
Future < void > _pull ( ) async {
2023-09-14 05:17:03 +03:00
List < UserPayload > tmpUsers = List . empty ( growable: true ) ;
if ( ! await _getUsers ( tmpUsers ) ) {
2023-06-17 15:48:58 +03:00
return ;
}
2023-09-14 05:17:03 +03:00
List < Peer > tmpPeers = List . empty ( growable: true ) ;
if ( ! await _getPeers ( tmpPeers ) ) {
2023-06-17 15:48:58 +03:00
return ;
}
2023-09-14 05:17:03 +03:00
// me first
var index = tmpUsers
. indexWhere ( ( user ) = > user . name = = gFFI . userModel . userName . value ) ;
if ( index ! = - 1 ) {
var user = tmpUsers . removeAt ( index ) ;
tmpUsers . insert ( 0 , user ) ;
}
users . value = tmpUsers ;
if ( ! users . any ( ( u ) = > u . name = = selectedUser . value ) ) {
selectedUser . value = ' ' ;
}
// recover online
final oldOnlineIDs = peers . where ( ( e ) = > e . online ) . map ( ( e ) = > e . id ) . toList ( ) ;
peers . value = tmpPeers ;
peers
. where ( ( e ) = > oldOnlineIDs . contains ( e . id ) )
. map ( ( e ) = > e . online = true )
. toList ( ) ;
groupLoadError . value = ' ' ;
}
Future < bool > _getUsers ( List < UserPayload > tmpUsers ) async {
2022-12-11 16:40:35 +03:00
final api = " ${ await bind . mainGetApiServer ( ) } /api/users " ;
try {
var uri0 = Uri . parse ( api ) ;
2023-09-14 05:17:03 +03:00
final pageSize = 100 ;
2022-12-11 16:40:35 +03:00
var total = 0 ;
2022-12-23 05:36:18 +03:00
int current = 0 ;
2022-12-11 16:40:35 +03:00
do {
2022-12-23 05:36:18 +03:00
current + = 1 ;
2022-12-11 16:40:35 +03:00
var uri = Uri (
scheme: uri0 . scheme ,
host: uri0 . host ,
path: uri0 . path ,
port: uri0 . port ,
queryParameters: {
' current ' : current . toString ( ) ,
' pageSize ' : pageSize . toString ( ) ,
2023-09-14 05:17:03 +03:00
' accessible ' : ' ' ,
' status ' : ' 1 ' ,
2022-12-11 16:40:35 +03:00
} ) ;
2023-01-06 13:26:19 +03:00
final resp = await http . get ( uri , headers: getHttpHeaders ( ) ) ;
2023-09-14 05:17:03 +03:00
_statusCode = resp . statusCode ;
Map < String , dynamic > json =
_jsonDecodeResp ( utf8 . decode ( resp . bodyBytes ) , resp . statusCode ) ;
if ( json . containsKey ( ' error ' ) ) {
2023-09-18 09:36:55 +03:00
if ( json [ ' error ' ] = = ' Admin required! ' | |
json [ ' error ' ]
. toString ( )
. contains ( ' ambiguous column name: status ' ) ) {
2023-09-14 05:17:03 +03:00
throw translate ( ' upgrade_rustdesk_server_pro_to_{1.1.10}_tip ' ) ;
2022-12-11 16:40:35 +03:00
} else {
2023-09-14 05:17:03 +03:00
throw json [ ' error ' ] ;
}
}
if ( resp . statusCode ! = 200 ) {
throw ' HTTP ${ resp . statusCode } ' ;
}
if ( json . containsKey ( ' total ' ) ) {
if ( total = = 0 ) total = json [ ' total ' ] ;
if ( json . containsKey ( ' data ' ) ) {
final data = json [ ' data ' ] ;
if ( data is List ) {
for ( final user in data ) {
final u = UserPayload . fromJson ( user ) ;
int index = tmpUsers . indexWhere ( ( e ) = > e . name = = u . name ) ;
if ( index < 0 ) {
tmpUsers . add ( u ) ;
} else {
tmpUsers [ index ] = u ;
2022-12-11 16:40:35 +03:00
}
}
}
}
}
2022-12-23 05:36:18 +03:00
} while ( current * pageSize < total ) ;
2023-09-14 05:17:03 +03:00
return true ;
2022-12-11 16:40:35 +03:00
} catch ( err ) {
2023-09-14 05:17:03 +03:00
debugPrint ( ' get accessible users: $ err ' ) ;
2023-09-24 03:36:53 +03:00
groupLoadError . value =
' ${ translate ( ' pull_group_failed_tip ' ) } : ${ translate ( err . toString ( ) ) } ' ;
2022-12-11 16:40:35 +03:00
}
2023-06-17 15:48:58 +03:00
return false ;
}
2023-09-14 05:17:03 +03:00
Future < bool > _getPeers ( List < Peer > tmpPeers ) async {
2022-12-11 16:40:35 +03:00
try {
2023-09-14 05:17:03 +03:00
final api = " ${ await bind . mainGetApiServer ( ) } /api/peers " ;
2022-12-11 16:40:35 +03:00
var uri0 = Uri . parse ( api ) ;
2023-09-14 05:17:03 +03:00
final pageSize = 100 ;
2022-12-11 16:40:35 +03:00
var total = 0 ;
2022-12-23 05:36:18 +03:00
int current = 0 ;
2022-12-11 16:40:35 +03:00
do {
2022-12-23 05:36:18 +03:00
current + = 1 ;
2023-09-19 07:03:45 +03:00
var queryParameters = {
' current ' : current . toString ( ) ,
' pageSize ' : pageSize . toString ( ) ,
' accessible ' : ' ' ,
' status ' : ' 1 ' ,
} ;
2022-12-11 16:40:35 +03:00
var uri = Uri (
scheme: uri0 . scheme ,
host: uri0 . host ,
path: uri0 . path ,
port: uri0 . port ,
2023-06-21 04:30:32 +03:00
queryParameters: queryParameters ) ;
2023-01-06 13:26:19 +03:00
final resp = await http . get ( uri , headers: getHttpHeaders ( ) ) ;
2023-09-14 05:17:03 +03:00
_statusCode = resp . statusCode ;
Map < String , dynamic > json =
_jsonDecodeResp ( utf8 . decode ( resp . bodyBytes ) , resp . statusCode ) ;
if ( json . containsKey ( ' error ' ) ) {
throw json [ ' error ' ] ;
}
if ( resp . statusCode ! = 200 ) {
throw ' HTTP ${ resp . statusCode } ' ;
}
if ( json . containsKey ( ' total ' ) ) {
if ( total = = 0 ) total = json [ ' total ' ] ;
if ( json . containsKey ( ' data ' ) ) {
final data = json [ ' data ' ] ;
if ( data is List ) {
for ( final p in data ) {
final peerPayload = PeerPayload . fromJson ( p ) ;
final peer = PeerPayload . toPeer ( peerPayload ) ;
int index = tmpPeers . indexWhere ( ( e ) = > e . id = = peer . id ) ;
if ( index < 0 ) {
tmpPeers . add ( peer ) ;
} else {
tmpPeers [ index ] = peer ;
}
2022-12-11 16:40:35 +03:00
}
}
}
}
2022-12-23 05:36:18 +03:00
} while ( current * pageSize < total ) ;
2023-09-14 05:17:03 +03:00
return true ;
2022-12-11 16:40:35 +03:00
} catch ( err ) {
2023-09-14 05:17:03 +03:00
debugPrint ( ' get accessible peers: $ err ' ) ;
2023-09-24 03:36:53 +03:00
groupLoadError . value =
' ${ translate ( ' pull_group_failed_tip ' ) } : ${ translate ( err . toString ( ) ) } ' ;
2023-09-14 05:17:03 +03:00
}
return false ;
}
Map < String , dynamic > _jsonDecodeResp ( String body , int statusCode ) {
try {
Map < String , dynamic > json = jsonDecode ( body ) ;
return json ;
} catch ( e ) {
final err = body . isNotEmpty & & body . length < 128 ? body : e . toString ( ) ;
if ( statusCode ! = 200 ) {
throw ' HTTP $ statusCode , $ err ' ;
}
throw err ;
}
}
void _saveCache ( ) {
try {
final map = ( < String , dynamic > {
" access_token " : bind . mainGetLocalOption ( key: ' access_token ' ) ,
" users " : users . map ( ( e ) = > e . toGroupCacheJson ( ) ) . toList ( ) ,
' peers ' : peers . map ( ( e ) = > e . toGroupCacheJson ( ) ) . toList ( )
} ) ;
bind . mainSaveGroup ( json: jsonEncode ( map ) ) ;
} catch ( e ) {
debugPrint ( ' group save: $ e ' ) ;
}
}
2023-09-24 12:56:35 +03:00
Future < void > loadCache ( ) async {
2023-09-14 05:17:03 +03:00
try {
if ( _cacheLoadOnceFlag | | groupLoading . value | | initialized ) return ;
_cacheLoadOnceFlag = true ;
final access_token = bind . mainGetLocalOption ( key: ' access_token ' ) ;
if ( access_token . isEmpty ) return ;
final cache = await bind . mainLoadGroup ( ) ;
if ( groupLoading . value ) return ;
final data = jsonDecode ( cache ) ;
if ( data = = null | | data [ ' access_token ' ] ! = access_token ) return ;
users . clear ( ) ;
peers . clear ( ) ;
if ( data [ ' users ' ] is List ) {
for ( var u in data [ ' users ' ] ) {
users . add ( UserPayload . fromJson ( u ) ) ;
}
}
if ( data [ ' peers ' ] is List ) {
for ( final peer in data [ ' peers ' ] ) {
peers . add ( Peer . fromJson ( peer ) ) ;
}
}
} catch ( e ) {
debugPrint ( " load group cache: $ e " ) ;
}
}
reset ( ) async {
groupLoadError . value = ' ' ;
users . clear ( ) ;
peers . clear ( ) ;
selectedUser . value = ' ' ;
await bind . mainClearGroup ( ) ;
2022-12-11 16:40:35 +03:00
}
}