mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-10-01 06:55:46 -04:00
refactor and move stuff
This commit is contained in:
parent
8c22bf8cc0
commit
b54868cc55
3
.gitignore
vendored
3
.gitignore
vendored
@ -42,3 +42,6 @@ app.*.map.json
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
# WASM
|
||||
/web/wasm/
|
13
_script_common
Normal file
13
_script_common
Normal file
@ -0,0 +1,13 @@
|
||||
set -eo pipefail
|
||||
|
||||
get_abs_filename() {
|
||||
# $1 : relative filename
|
||||
echo "$(cd "$(dirname "$1")" && pwd)/$(basename "$1")"
|
||||
}
|
||||
|
||||
# Veilid location
|
||||
VEILIDDIR=$(get_abs_filename "$SCRIPTDIR/../veilid")
|
||||
if [ ! -d "$VEILIDDIR" ]; then
|
||||
echo 'Veilid git clone needs to be at $VEILIDDIR'
|
||||
exit 1
|
||||
fi
|
20
lib/entities/profile.dart
Normal file
20
lib/entities/profile.dart
Normal file
@ -0,0 +1,20 @@
|
||||
class Profile {
|
||||
String name;
|
||||
String publicKey;
|
||||
bool invisible;
|
||||
|
||||
Profile(this.name, this.publicKey) : invisible = false;
|
||||
|
||||
Profile.fromJson(Map<String, dynamic> json)
|
||||
: name = json['name'],
|
||||
publicKey = json['public_key'],
|
||||
invisible = json['invisible'];
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'name': name,
|
||||
'public_key': publicKey,
|
||||
'invisible': invisible,
|
||||
};
|
||||
}
|
||||
}
|
2
lib/log/log.dart
Normal file
2
lib/log/log.dart
Normal file
@ -0,0 +1,2 @@
|
||||
export 'loggy.dart';
|
||||
export 'state_logger.dart';
|
@ -15,12 +15,12 @@ class ChatPage extends ConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text("Home Page"),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
ref.watch(authNotifierProvider.notifier).logout();
|
||||
},
|
||||
child: const Text("Logout"),
|
||||
),
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// ref.watch(authNotifierProvider.notifier).logout();
|
||||
// },
|
||||
// child: const Text("Logout"),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -15,12 +15,12 @@ class HomePage extends ConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text("Home Page"),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
ref.watch(authNotifierProvider.notifier).logout();
|
||||
},
|
||||
child: const Text("Logout"),
|
||||
),
|
||||
// ElevatedButton(
|
||||
// onPressed: () {
|
||||
// ref.watch(authNotifierProvider.notifier).logout();
|
||||
// },
|
||||
// child: const Text("Logout"),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -15,15 +15,15 @@ class LoginPage extends ConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text("Login Page"),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
ref.watch(authNotifierProvider.notifier).login(
|
||||
"myEmail",
|
||||
"myPassword",
|
||||
);
|
||||
},
|
||||
child: const Text("Login"),
|
||||
),
|
||||
// ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// ref.watch(authNotifierProvider.notifier).login(
|
||||
// "myEmail",
|
||||
// "myPassword",
|
||||
// );
|
||||
// },
|
||||
// child: const Text("Login"),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
class NewAccountPage extends ConsumerWidget {
|
||||
const NewAccountPage({super.key});
|
||||
static const path = '/new_account';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
appBar: null,
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text("New Account Page"),
|
||||
// ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// ref.watch(authNotifierProvider.notifier).login(
|
||||
// "myEmail",
|
||||
// "myPassword",
|
||||
// );
|
||||
// },
|
||||
// child: const Text("Login"),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -1,2 +1,4 @@
|
||||
export 'home.dart';
|
||||
export 'splash.dart';
|
||||
export 'index.dart';
|
||||
export 'login.dart';
|
||||
export 'new_account.dart';
|
||||
|
@ -0,0 +1,32 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
class LoginPage extends ConsumerWidget {
|
||||
const LoginPage({super.key});
|
||||
static const path = '/settings';
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
return Scaffold(
|
||||
appBar: null,
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Text("Settings Page"),
|
||||
// ElevatedButton(
|
||||
// onPressed: () async {
|
||||
// ref.watch(authNotifierProvider.notifier).login(
|
||||
// "myEmail",
|
||||
// "myPassword",
|
||||
// );
|
||||
// },
|
||||
// child: const Text("Login"),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../pages/pages.dart';
|
||||
import 'router_notifier.dart';
|
||||
|
||||
final _key = GlobalKey<NavigatorState>(debugLabel: 'routerKey');
|
||||
@ -14,7 +15,7 @@ final routerProvider = Provider.autoDispose<GoRouter>((ref) {
|
||||
navigatorKey: _key,
|
||||
refreshListenable: notifier,
|
||||
debugLogDiagnostics: true,
|
||||
initialLocation: SplashPage.path,
|
||||
initialLocation: IndexPage.path,
|
||||
routes: notifier.routes,
|
||||
redirect: notifier.redirect,
|
||||
);
|
||||
|
@ -1,12 +1,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
|
||||
import '../entities/user_role.dart';
|
||||
import '../pages/pages.dart';
|
||||
import '../state/auth.dart';
|
||||
import '../state/permissions.dart';
|
||||
|
||||
/// This notifier is meant to implement the [Listenable] our [GoRouter] needs.
|
||||
///
|
||||
@ -45,9 +42,9 @@ class RouterNotifier extends AutoDisposeAsyncNotifier<void>
|
||||
String? redirect(BuildContext context, GoRouterState state) {
|
||||
if (this.state.isLoading || this.state.hasError) return null;
|
||||
|
||||
final isSplash = state.location == IndexPage.path;
|
||||
final isIndex = state.location == IndexPage.path;
|
||||
|
||||
if (isSplash) {
|
||||
if (isIndex) {
|
||||
return isAuth ? HomePage.path : LoginPage.path;
|
||||
}
|
||||
|
||||
@ -57,7 +54,7 @@ class RouterNotifier extends AutoDisposeAsyncNotifier<void>
|
||||
return isAuth ? null : IndexPage.path;
|
||||
}
|
||||
|
||||
/// Our application routes. Obtained through code generation
|
||||
/// Our application routes
|
||||
List<GoRoute> get routes => [
|
||||
GoRoute(
|
||||
path: IndexPage.path,
|
||||
@ -66,38 +63,43 @@ class RouterNotifier extends AutoDisposeAsyncNotifier<void>
|
||||
GoRoute(
|
||||
path: HomePage.path,
|
||||
builder: (context, state) => const HomePage(),
|
||||
redirect: (context, state) async {
|
||||
if (state.location == HomePage.path) return null;
|
||||
// redirect: (context, state) async {
|
||||
// if (state.location == HomePage.path) return null;
|
||||
|
||||
final roleListener = ProviderScope.containerOf(context).listen(
|
||||
permissionsProvider.select((value) => value.valueOrNull),
|
||||
(previous, next) {},
|
||||
);
|
||||
// // final roleListener = ProviderScope.containerOf(context).listen(
|
||||
// // permissionsProvider.select((value) => value.valueOrNull),
|
||||
// // (previous, next) {},
|
||||
// // );
|
||||
|
||||
final userRole = roleListener.read();
|
||||
final redirectTo = userRole?.redirectBasedOn(state.location);
|
||||
// // final userRole = roleListener.read();
|
||||
// // final redirectTo = userRole?.redirectBasedOn(state.location);
|
||||
|
||||
roleListener.close();
|
||||
return redirectTo;
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: AdminPage.path,
|
||||
builder: (context, state) => const AdminPage(),
|
||||
// // roleListener.close();
|
||||
// // return redirectTo;
|
||||
// },
|
||||
// routes: [
|
||||
// GoRoute(
|
||||
// path: AdminPage.path,
|
||||
// builder: (context, state) => const AdminPage(),
|
||||
// ),
|
||||
// GoRoute(
|
||||
// path: UserPage.path,
|
||||
// builder: (context, state) => const UserPage(),
|
||||
// ),
|
||||
// GoRoute(
|
||||
// path: GuestPage.path,
|
||||
// builder: (context, state) => const GuestPage(),
|
||||
// )
|
||||
// ]
|
||||
),
|
||||
GoRoute(
|
||||
path: UserPage.path,
|
||||
builder: (context, state) => const UserPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: GuestPage.path,
|
||||
builder: (context, state) => const GuestPage(),
|
||||
)
|
||||
]),
|
||||
GoRoute(
|
||||
path: LoginPage.path,
|
||||
builder: (context, state) => const LoginPage(),
|
||||
),
|
||||
GoRoute(
|
||||
path: NewAccountPage.path,
|
||||
builder: (context, state) => const NewAccountPage(),
|
||||
),
|
||||
];
|
||||
|
||||
/// Adds [GoRouter]'s listener as specified by its [Listenable].
|
||||
@ -127,20 +129,20 @@ final routerNotifierProvider =
|
||||
});
|
||||
|
||||
/// A simple extension to determine wherever should we redirect our users
|
||||
extension RedirecttionBasedOnRole on UserRole {
|
||||
/// Redirects the users based on [this] and its current [location]
|
||||
String? redirectBasedOn(String location) {
|
||||
switch (this) {
|
||||
case UserRole.admin:
|
||||
return null;
|
||||
case UserRole.verifiedUser:
|
||||
case UserRole.unverifiedUser:
|
||||
if (location == AdminPage.path) return HomePage.path;
|
||||
return null;
|
||||
case UserRole.guest:
|
||||
case UserRole.none:
|
||||
if (location != HomePage.path) return HomePage.path;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
// extension RedirecttionBasedOnRole on UserRole {
|
||||
// /// Redirects the users based on [this] and its current [location]
|
||||
// String? redirectBasedOn(String location) {
|
||||
// switch (this) {
|
||||
// case UserRole.admin:
|
||||
// return null;
|
||||
// case UserRole.verifiedUser:
|
||||
// case UserRole.unverifiedUser:
|
||||
// if (location == AdminPage.path) return HomePage.path;
|
||||
// return null;
|
||||
// case UserRole.guest:
|
||||
// case UserRole.none:
|
||||
// if (location != HomePage.path) return HomePage.path;
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
110
lib/state/auth.dart
Normal file
110
lib/state/auth.dart
Normal file
@ -0,0 +1,110 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class User {
|
||||
final String publicKey;
|
||||
final String secretKey;
|
||||
const User(this.publicKey, this.secretKey);
|
||||
}
|
||||
|
||||
/// A mock of an Authenticated User
|
||||
const _dummyUser = User("", "");
|
||||
|
||||
/// XXXX THIS IS TOTALLY BOGUS FOR NOW
|
||||
/// This notifier holds and handles the authentication state of the application
|
||||
class AuthNotifier extends AutoDisposeAsyncNotifier<User?> {
|
||||
late SharedPreferences sharedPreferences;
|
||||
static const _sharedPrefsKey = 'token';
|
||||
|
||||
/// Mock of the duration of a network request
|
||||
@override
|
||||
FutureOr<User?> build() async {
|
||||
sharedPreferences = await SharedPreferences.getInstance();
|
||||
|
||||
_persistenceRefreshLogic();
|
||||
|
||||
return await _loginRecoveryAttempt();
|
||||
}
|
||||
|
||||
/// Tries to perform a login with the saved token on the persistant storage.
|
||||
/// If _anything_ goes wrong, deletes the internal token and returns a [User.signedOut].
|
||||
Future<User?> _loginRecoveryAttempt() async {
|
||||
try {
|
||||
final savedToken = sharedPreferences.getString(_sharedPrefsKey);
|
||||
if (savedToken == null) {
|
||||
throw const UnauthorizedException(
|
||||
"Couldn't find the authentication token");
|
||||
}
|
||||
|
||||
return await _loginWithToken(savedToken);
|
||||
} catch (_, __) {
|
||||
await sharedPreferences.remove(_sharedPrefsKey);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// Mock of a request performed on logout (might be common, or not, whatevs).
|
||||
Future<void> logout() async {
|
||||
await Future.delayed(networkRoundTripTime);
|
||||
state = const AsyncValue.data(null);
|
||||
}
|
||||
|
||||
/// Mock of a successful login attempt, which results come from the network.
|
||||
Future<void> login(String publicKey, String password) async {
|
||||
state = await AsyncValue.guard<User>(() async {
|
||||
return Future.delayed(
|
||||
networkRoundTripTime,
|
||||
() => _dummyUser,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Mock of a login request performed with a saved token.
|
||||
/// If such request fails, this method will throw an [UnauthorizedException].
|
||||
Future<User> _loginWithToken(String token) async {
|
||||
final logInAttempt = await Future.delayed(
|
||||
networkRoundTripTime,
|
||||
() => true,
|
||||
);
|
||||
|
||||
if (logInAttempt) return _dummyUser;
|
||||
|
||||
throw const UnauthorizedException('401 Unauthorized or something');
|
||||
}
|
||||
|
||||
/// Internal method used to listen authentication state changes.
|
||||
/// When the auth object is in a loading state, nothing happens.
|
||||
/// When the auth object is in a error state, we choose to remove the token
|
||||
/// Otherwise, we expect the current auth value to be reflected in our persistence API
|
||||
void _persistenceRefreshLogic() {
|
||||
ref.listenSelf((_, next) {
|
||||
if (next.isLoading) return;
|
||||
if (next.hasError) {
|
||||
sharedPreferences.remove(_sharedPrefsKey);
|
||||
return;
|
||||
}
|
||||
|
||||
final val = next.requireValue;
|
||||
final isAuthenticated = val == null;
|
||||
|
||||
isAuthenticated
|
||||
? sharedPreferences.remove(_sharedPrefsKey)
|
||||
: sharedPreferences.setString(_sharedPrefsKey, val.publicKey);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
final authNotifierProvider =
|
||||
AutoDisposeAsyncNotifierProvider<AuthNotifier, User?>(() {
|
||||
return AuthNotifier();
|
||||
});
|
||||
|
||||
class UnauthorizedException implements Exception {
|
||||
final String message;
|
||||
const UnauthorizedException(this.message);
|
||||
}
|
||||
|
||||
/// Mock of the duration of a network request
|
||||
const networkRoundTripTime = Duration(milliseconds: 750);
|
@ -0,0 +1,16 @@
|
||||
import '../tools/tools.dart';
|
||||
|
||||
enum ConnectionState {
|
||||
detached,
|
||||
detaching,
|
||||
attaching,
|
||||
attachedWeak,
|
||||
attachedGood,
|
||||
attachedStrong,
|
||||
fullyAttached,
|
||||
overAttached,
|
||||
}
|
||||
|
||||
ExternalStreamState<ConnectionState> globalConnectionState =
|
||||
ExternalStreamState<ConnectionState>(ConnectionState.detached);
|
||||
var globalConnectionStateProvider = globalConnectionState.provider();
|
2
lib/state/state.dart
Normal file
2
lib/state/state.dart
Normal file
@ -0,0 +1,2 @@
|
||||
export 'connection_state.dart';
|
||||
export 'auth.dart';
|
@ -1,6 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'themes.dart';
|
||||
import 'themes/themes.dart';
|
||||
|
||||
class ThemeService {
|
||||
ThemeService._();
|
||||
@ -18,9 +18,6 @@ class ThemeService {
|
||||
final allThemes = <String, ThemeData>{
|
||||
'dark': darkTheme,
|
||||
'light': lightTheme,
|
||||
'pink': pinkTheme,
|
||||
'darkBlue': darkBlueTheme,
|
||||
'halloween': halloweenTheme,
|
||||
};
|
||||
|
||||
String get previousThemeName {
|
||||
|
19
lib/theme/themes/dark.dart
Normal file
19
lib/theme/themes/dark.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
ThemeData darkTheme = ThemeData.dark();
|
||||
|
||||
// late Color primaryColor = const Color(0xFF343455);
|
||||
// late Color secondaryColor = const Color(0xFF3D3E77);
|
||||
// late Color tertiaryColor = const Color(0xFFBB108E);
|
||||
// late Color alternate = const Color(0xFF5086DF);
|
||||
// late Color primaryBackground = const Color(0xFF252534);
|
||||
// late Color secondaryBackground = const Color(0xFF292D44);
|
||||
// late Color primaryText = const Color(0xFFD0D0E0);
|
||||
// late Color secondaryText = const Color(0xFFB0B0D0);
|
||||
|
||||
// late Color disabledText = Color(0x808F8F8F);
|
||||
// late Color primaryEdge = Color(0xFF555594);
|
||||
// late Color header = Color(0xFF8A8AD8);
|
||||
// late Color textBackground = Color(0xFF181820);
|
||||
// late Color active = Color(0xFF463BAD);
|
||||
// late Color inactive = Color(0xFF2E2E3C);
|
19
lib/theme/themes/light.dart
Normal file
19
lib/theme/themes/light.dart
Normal file
@ -0,0 +1,19 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
ThemeData lightTheme = ThemeData.light();
|
||||
|
||||
// late Color primaryColor = const Color(0xFF6667AB);
|
||||
// late Color secondaryColor = const Color(0xFF7C7ED0);
|
||||
// late Color tertiaryColor = const Color(0xFFF259C9);
|
||||
// late Color alternate = const Color(0xFF77ABFF);
|
||||
// late Color primaryBackground = const Color(0xFFA0A0D0);
|
||||
// late Color secondaryBackground = const Color(0xFFB0B0D0);
|
||||
// late Color primaryText = const Color(0xFF101010);
|
||||
// late Color secondaryText = const Color(0xFF282840);
|
||||
|
||||
// late Color disabledText = Color(0x8047464F);
|
||||
// late Color primaryEdge = Color(0xFF44447F);
|
||||
// late Color header = Color(0xFFE0E0F0);
|
||||
// late Color textBackground = Color(0xFFE0E0F0);
|
||||
// late Color active = Color(0xFF5B4FFA);
|
||||
// late Color inactive = Color(0xFF3E3E72);
|
2
lib/theme/themes/themes.dart
Normal file
2
lib/theme/themes/themes.dart
Normal file
@ -0,0 +1,2 @@
|
||||
export 'light.dart';
|
||||
export 'dark.dart';
|
27
lib/tools/external_stream_state.dart
Normal file
27
lib/tools/external_stream_state.dart
Normal file
@ -0,0 +1,27 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
// Caches a state value which can be changed from anywhere
|
||||
// Creates a provider interface that notices when the value changes
|
||||
class ExternalStreamState<T> {
|
||||
T currentState;
|
||||
StreamController<T> streamController;
|
||||
ExternalStreamState(T initialState)
|
||||
: currentState = initialState,
|
||||
streamController = StreamController<T>.broadcast();
|
||||
void add(T newState) {
|
||||
currentState = newState;
|
||||
streamController.add(newState);
|
||||
}
|
||||
|
||||
AutoDisposeStreamProvider<T> provider() {
|
||||
return AutoDisposeStreamProvider<T>((ref) async* {
|
||||
if (await streamController.stream.isEmpty) {
|
||||
yield currentState;
|
||||
}
|
||||
await for (final value in streamController.stream) {
|
||||
yield value;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
1
lib/tools/tools.dart
Normal file
1
lib/tools/tools.dart
Normal file
@ -0,0 +1 @@
|
||||
export 'external_stream_state.dart';
|
@ -14,7 +14,7 @@ Future<String> getVeilidVersion() async {
|
||||
|
||||
// Initialize Veilid
|
||||
// Call only once.
|
||||
void _init() {
|
||||
void _initVeilid() {
|
||||
if (kIsWeb) {
|
||||
var platformConfig = VeilidWASMConfig(
|
||||
logging: VeilidWASMConfigLogging(
|
||||
@ -44,7 +44,6 @@ void _init() {
|
||||
}
|
||||
}
|
||||
|
||||
// Called from FlutterFlow stub initialize() function upon Main page load
|
||||
bool initialized = false;
|
||||
Processor processor = Processor();
|
||||
|
||||
@ -54,7 +53,7 @@ Future<void> initializeVeilid() async {
|
||||
}
|
||||
|
||||
// Init Veilid
|
||||
_init();
|
||||
_initVeilid();
|
||||
|
||||
// Startup Veilid
|
||||
await processor.startup();
|
||||
|
@ -2,7 +2,8 @@ import 'dart:async';
|
||||
import 'package:veilid/veilid.dart';
|
||||
import 'config.dart';
|
||||
import 'veilid_log.dart';
|
||||
import '../log/loggy.dart';
|
||||
import '../log/log.dart';
|
||||
import '../state/state.dart';
|
||||
|
||||
class Processor {
|
||||
String _veilidVersion = "";
|
||||
@ -57,48 +58,46 @@ class Processor {
|
||||
//loggy.info("Attachment: ${updateAttachment.json}");
|
||||
|
||||
// Set connection meter and ui state for connection state
|
||||
var connectionState = "";
|
||||
var cs = ConnectionState.detached;
|
||||
var checkPublicInternet = false;
|
||||
switch (updateAttachment.state.state) {
|
||||
case AttachmentState.detached:
|
||||
connectionState = "detached";
|
||||
cs = ConnectionState.detached;
|
||||
break;
|
||||
case AttachmentState.detaching:
|
||||
connectionState = "detaching";
|
||||
cs = ConnectionState.detaching;
|
||||
break;
|
||||
case AttachmentState.attaching:
|
||||
connectionState = "attaching";
|
||||
cs = ConnectionState.attaching;
|
||||
break;
|
||||
case AttachmentState.attachedWeak:
|
||||
checkPublicInternet = true;
|
||||
connectionState = "weak";
|
||||
cs = ConnectionState.attachedWeak;
|
||||
break;
|
||||
case AttachmentState.attachedGood:
|
||||
checkPublicInternet = true;
|
||||
connectionState = "good";
|
||||
cs = ConnectionState.attachedGood;
|
||||
break;
|
||||
case AttachmentState.attachedStrong:
|
||||
checkPublicInternet = true;
|
||||
connectionState = "strong";
|
||||
cs = ConnectionState.attachedStrong;
|
||||
break;
|
||||
case AttachmentState.fullyAttached:
|
||||
checkPublicInternet = true;
|
||||
connectionState = "full";
|
||||
cs = ConnectionState.fullyAttached;
|
||||
break;
|
||||
case AttachmentState.overAttached:
|
||||
checkPublicInternet = true;
|
||||
connectionState = "over";
|
||||
cs = ConnectionState.overAttached;
|
||||
break;
|
||||
}
|
||||
if (checkPublicInternet) {
|
||||
if (!updateAttachment.state.publicInternetReady) {
|
||||
connectionState = "attaching";
|
||||
cs = ConnectionState.attaching;
|
||||
}
|
||||
}
|
||||
|
||||
FFAppState().update(() {
|
||||
FFAppState().ConnectionState = connectionState;
|
||||
});
|
||||
globalConnectionState.add(cs);
|
||||
}
|
||||
|
||||
Future<void> processUpdateConfig(VeilidUpdateConfig updateConfig) async {
|
||||
|
@ -0,0 +1,5 @@
|
||||
export 'config.dart';
|
||||
export 'processor.dart';
|
||||
export 'tools.dart';
|
||||
export 'veilid_log.dart';
|
||||
export 'init.dart';
|
41
setup_linux.sh
Executable file
41
setup_linux.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source $SCRIPTDIR/_script_common
|
||||
|
||||
if [[ "$(uname)" != "Linux" ]]; then
|
||||
echo Not running Linux
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(lsb_release -d | grep -qEi 'debian|buntu|mint')" ]; then
|
||||
echo Not a supported Linux
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# # ensure unzip is installed
|
||||
# if command -v unzip &> /dev/null; then
|
||||
# echo '[X] unzip is available in the path'
|
||||
# else
|
||||
# echo 'unzip is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# # ensure rsync is installed
|
||||
# if command -v rsync &> /dev/null; then
|
||||
# echo '[X] rsync is available in the path'
|
||||
# else
|
||||
# echo 'rsync is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# # ensure sed is installed
|
||||
# if command -v sed &> /dev/null; then
|
||||
# echo '[X] sed is available in the path'
|
||||
# else
|
||||
# echo 'sed is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# run setup for veilid
|
||||
$VEILIDDIR/setup_linux.sh
|
||||
|
36
setup_macos.sh
Executable file
36
setup_macos.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source $SCRIPTDIR/_script_common
|
||||
|
||||
if [[ "$(uname)" != "Darwin" ]]; then
|
||||
echo Not running MacOS
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# # ensure unzip is installed
|
||||
# if command -v unzip &> /dev/null; then
|
||||
# echo '[X] unzip is available in the path'
|
||||
# else
|
||||
# echo 'unzip is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# # ensure rsync is installed
|
||||
# if command -v rsync &> /dev/null; then
|
||||
# echo '[X] rsync is available in the path'
|
||||
# else
|
||||
# echo 'rsync is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# # ensure sed is installed
|
||||
# if command -v sed &> /dev/null; then
|
||||
# echo '[X] sed is available in the path'
|
||||
# else
|
||||
# echo 'sed is not available in the path'
|
||||
# exit 1
|
||||
# fi
|
||||
|
||||
# run setup for veilid
|
||||
$VEILIDDIR/setup_macos.sh
|
||||
|
25
wasm_update.sh
Executable file
25
wasm_update.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
source $SCRIPTDIR/_script_common
|
||||
|
||||
pushd $SCRIPTDIR >/dev/null
|
||||
|
||||
# WASM output dir
|
||||
WASMDIR=$SCRIPTDIR/web/wasm
|
||||
|
||||
# Build veilid-wasm, passing any arguments here to the build script
|
||||
pushd $VEILIDDIR/veilid-wasm >/dev/null
|
||||
PKGDIR=$(./wasm_build.sh $@ | grep SUCCESS:OUTPUTDIR | cut -d= -f2)
|
||||
popd >/dev/null
|
||||
|
||||
# Copy wasm blob into place
|
||||
echo Updating WASM from $PKGDIR to $WASMDIR
|
||||
if [ -d $WASMDIR ]; then
|
||||
rm -f $WASMDIR/*
|
||||
fi
|
||||
mkdir -p $WASMDIR
|
||||
cp -f $PKGDIR/* $WASMDIR/
|
||||
|
||||
#### Done
|
||||
|
||||
popd >/dev/null
|
Loading…
Reference in New Issue
Block a user