mirror of
https://gitlab.com/comunic/comunicmobile
synced 2025-07-01 14:13:29 +00:00
Compare commits
100 Commits
Author | SHA1 | Date | |
---|---|---|---|
18cb8be655 | |||
c5ee235ebd | |||
a24bb147c8 | |||
ae56635564 | |||
c02f6f1deb | |||
31fed62616 | |||
aff7e7434c | |||
f18b632ac8 | |||
b14eae6689 | |||
bae83430ab | |||
2c44793def | |||
b86a456a03 | |||
e969c85188 | |||
de8b4f7fb4 | |||
f624971717 | |||
49a1098a28 | |||
64bbce2084 | |||
504be2e5ef | |||
79ed8e934e | |||
1bd7840be6 | |||
e80232931e | |||
20b19d0a4a | |||
ec16984b8a | |||
80a1c4e0c4 | |||
512b058d34 | |||
73f20a543d | |||
2ee4590364 | |||
2a50190e94 | |||
5040fbb101 | |||
11829273e2 | |||
56c5eb335b | |||
0bd7426813 | |||
75c596226b | |||
a0abdc4f1b | |||
2ac5caaf96 | |||
98354ee3cc | |||
9e6d3761fe | |||
48c9ee37b6 | |||
41446f0e5b | |||
0f9a59b4a7 | |||
f0f7096c94 | |||
adbc036c16 | |||
45e8f34c81 | |||
06312512a6 | |||
5398970868 | |||
820491b09a | |||
7a0b44e446 | |||
299a95ea45 | |||
3a997cdc56 | |||
ab2c5da0da | |||
2424fd38d6 | |||
3c08384a4f | |||
c199540aff | |||
49a9186978 | |||
1f3230363e | |||
1a4988d192 | |||
cd7cafe315 | |||
42b4f99efa | |||
173487f801 | |||
61e279f719 | |||
94ae3434e4 | |||
78ae2a574a | |||
75b06e7df8 | |||
71a72d4f04 | |||
90b3ffbe81 | |||
bfe932c053 | |||
4fd8c4d613 | |||
ecc4f5bffe | |||
c849ee0bac | |||
04114dede1 | |||
fff33f907a | |||
9a82301c52 | |||
48ececf93c | |||
bc6068c2a1 | |||
5b680bb922 | |||
2b05fbda35 | |||
30494ff74a | |||
062abc5a03 | |||
21506f769e | |||
e180f0bc13 | |||
7ae50e21a4 | |||
ae75429b1d | |||
f2380ba60a | |||
b4140e61ad | |||
aa44688d66 | |||
45cd7f1481 | |||
a076c08429 | |||
fa8c1f46a1 | |||
0b4306990a | |||
4e7950582a | |||
3c179d4b83 | |||
622c1a5abf | |||
48eb525f18 | |||
acb24b0b36 | |||
b9fe15e190 | |||
98b9c44315 | |||
1f0fa1faaa | |||
a92664ac81 | |||
06d1d08f6d | |||
77030609c0 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -74,3 +74,5 @@ lib/*private*.dart
|
|||||||
|
|
||||||
.flutter-plugins-dependencies
|
.flutter-plugins-dependencies
|
||||||
|
|
||||||
|
local.properties
|
||||||
|
.gradle
|
||||||
|
@ -22,6 +22,7 @@ if (flutterVersionName == null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
apply plugin: 'kotlin-android'
|
||||||
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
|
||||||
|
|
||||||
|
|
||||||
@ -33,24 +34,33 @@ if (keystorePropertiesFile.exists()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 30
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|
||||||
// Required to use WebRTC
|
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '1.8'
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main.java.srcDirs += 'src/main/java'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'InvalidPackage'
|
disable 'InvalidPackage'
|
||||||
|
|
||||||
|
// TODO remove this fix to use Gradle plugin 4 ASAP
|
||||||
|
checkReleaseBuilds false
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "org.communiquons.comunic"
|
applicationId "org.communiquons.comunic"
|
||||||
minSdkVersion 21
|
minSdkVersion 23
|
||||||
targetSdkVersion 30
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
@ -76,9 +86,7 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
useProguard true
|
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,10 +117,11 @@ flutter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'com.neovisionaries:nv-websocket-client:2.14'
|
implementation 'com.neovisionaries:nv-websocket-client:2.14'
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13.1'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
@ -59,7 +59,8 @@
|
|||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/LaunchTheme"
|
android:theme="@style/LaunchTheme"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize"
|
||||||
|
android:exported="true">
|
||||||
<!-- This keeps the window background of the activity showing
|
<!-- This keeps the window background of the activity showing
|
||||||
until Flutter renders its first frame. It can be removed if
|
until Flutter renders its first frame. It can be removed if
|
||||||
there is no splash screen (such as the default splash screen
|
there is no splash screen (such as the default splash screen
|
||||||
@ -69,12 +70,6 @@
|
|||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme" />
|
android:resource="@style/NormalTheme" />
|
||||||
|
|
||||||
<!-- Specify that the launch screen should continue being displayed -->
|
|
||||||
<!-- until Flutter renders its first frame. -->
|
|
||||||
<meta-data
|
|
||||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
|
||||||
android:resource="@drawable/launch_background" />
|
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
@ -100,7 +100,10 @@ public class NotificationsService extends Service implements Runnable {
|
|||||||
|
|
||||||
Intent notificationIntent = new Intent(this, MainActivity.class);
|
Intent notificationIntent = new Intent(this, MainActivity.class);
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(this,
|
PendingIntent pendingIntent = PendingIntent.getActivity(this,
|
||||||
0, notificationIntent, 0);
|
0,
|
||||||
|
notificationIntent,
|
||||||
|
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0);
|
||||||
|
|
||||||
Notification notification = new NotificationCompat.Builder(this, SVC_CHANNEL_ID)
|
Notification notification = new NotificationCompat.Builder(this, SVC_CHANNEL_ID)
|
||||||
.setContentTitle("Comunic")
|
.setContentTitle("Comunic")
|
||||||
.setContentText(getText(R.string.independent_push_notification_notification_text))
|
.setContentText(getText(R.string.independent_push_notification_notification_text))
|
||||||
@ -197,12 +200,12 @@ public class NotificationsService extends Service implements Runnable {
|
|||||||
ws.setPingInterval(PING_INTERVAL);
|
ws.setPingInterval(PING_INTERVAL);
|
||||||
ws.addListener(new WebSocketAdapter() {
|
ws.addListener(new WebSocketAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) throws Exception {
|
public void onConnected(WebSocket websocket, Map<String, List<String>> headers) {
|
||||||
Log.v(TAG, "Connected to independent push notifications service!");
|
Log.v(TAG, "Connected to independent push notifications service!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDisconnected(WebSocket websocket, WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame, boolean closedByServer) throws Exception {
|
public void onDisconnected(WebSocket websocket, WebSocketFrame serverCloseFrame, WebSocketFrame clientCloseFrame, boolean closedByServer) {
|
||||||
Log.v(TAG, "Disconnected from independent push notifications websocket!");
|
Log.v(TAG, "Disconnected from independent push notifications websocket!");
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
lock.notify();
|
lock.notify();
|
||||||
@ -210,12 +213,12 @@ public class NotificationsService extends Service implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) throws Exception {
|
public void onTextFrame(WebSocket websocket, WebSocketFrame frame) {
|
||||||
handleTextFrame(frame);
|
handleTextFrame(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onError(WebSocket websocket, WebSocketException cause) throws Exception {
|
public void onError(WebSocket websocket, WebSocketException cause) {
|
||||||
Log.e(TAG, "An error occured, closing WebSocket!");
|
Log.e(TAG, "An error occured, closing WebSocket!");
|
||||||
cause.printStackTrace();
|
cause.printStackTrace();
|
||||||
websocket.disconnect();
|
websocket.disconnect();
|
||||||
@ -254,17 +257,14 @@ public class NotificationsService extends Service implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dropNotification(String id) throws Exception {
|
private void dropNotification(String id) {
|
||||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
NotificationManagerCompat notifManager = NotificationManagerCompat.from(NotificationsService.this);
|
NotificationManagerCompat notifManager = NotificationManagerCompat.from(NotificationsService.this);
|
||||||
notifManager.cancel(id, NOTIFS_ID);
|
notifManager.cancel(id, NOTIFS_ID);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendNotification(PushNotification n) throws Exception {
|
private void sendNotification(PushNotification n) {
|
||||||
new Handler(Looper.getMainLooper()).post(() -> postNotification(n));
|
new Handler(Looper.getMainLooper()).post(() -> postNotification(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -273,7 +273,12 @@ public class NotificationsService extends Service implements Runnable {
|
|||||||
createPushNotificationChannel();
|
createPushNotificationChannel();
|
||||||
|
|
||||||
Intent intent = new Intent(this, MainActivity.class);
|
Intent intent = new Intent(this, MainActivity.class);
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
|
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
intent,
|
||||||
|
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M ? PendingIntent.FLAG_IMMUTABLE : 0
|
||||||
|
);
|
||||||
|
|
||||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFS_CHANNEL_ID)
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFS_CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.ic_notifications)
|
.setSmallIcon(R.drawable.ic_notifications)
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
package org.communiquons.comunic
|
|
||||||
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
|
||||||
}
|
|
@ -1,21 +1,23 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.5.30'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.4'
|
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||||
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// Firebase
|
// Firebase
|
||||||
classpath 'com.google.gms:google-services:4.3.5'
|
classpath 'com.google.gms:google-services:4.3.10'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
|
||||||
|
@ -340,6 +340,7 @@
|
|||||||
"Failed to remove conversation logo!": "Erreur lors de la suppression du logo de la conversation !",
|
"Failed to remove conversation logo!": "Erreur lors de la suppression du logo de la conversation !",
|
||||||
"Failed to remove member!": "Echec de la suppression d'un membre !",
|
"Failed to remove member!": "Echec de la suppression d'un membre !",
|
||||||
"Failed to send a file!": "Erreur lors de l'envoi d'un fichier !",
|
"Failed to send a file!": "Erreur lors de l'envoi d'un fichier !",
|
||||||
|
"Failed to send report!": "Erreur lors de l'envoi du signalement !",
|
||||||
"Failed to start recording!": "Erreur lors du lancement de l'enregistrement !",
|
"Failed to start recording!": "Erreur lors du lancement de l'enregistrement !",
|
||||||
"Failed to toggle admin status of user!": "Echec du changement du status administrateur d'un membre !",
|
"Failed to toggle admin status of user!": "Echec du changement du status administrateur d'un membre !",
|
||||||
"Failed to update conversation settings!": "Echec de la mise à jour des paramètres de la conversation !",
|
"Failed to update conversation settings!": "Echec de la mise à jour des paramètres de la conversation !",
|
||||||
@ -500,6 +501,7 @@
|
|||||||
"Please check back soon!": "Revenez plus tard finir la configuration de l'application !",
|
"Please check back soon!": "Revenez plus tard finir la configuration de l'application !",
|
||||||
"Please choose new account image visibility level:": "Veuillez choisir un nouveau niveau de visibilité pour votre image de compte :",
|
"Please choose new account image visibility level:": "Veuillez choisir un nouveau niveau de visibilité pour votre image de compte :",
|
||||||
"Please choose now the Forez group you want to join...": "Veuillez maintenant choisir le groupe #Forez que vous souhaitez rejoindre...",
|
"Please choose now the Forez group you want to join...": "Veuillez maintenant choisir le groupe #Forez que vous souhaitez rejoindre...",
|
||||||
|
"Please choose the reason of your report:": "Veuillez indiquer la raison de votre signalement",
|
||||||
"Please click on the day you will be in the plain, so that everyone gets informed ! ;)": "Veuillez cliquer sur les jours où vous serez présent dans la plaine du Forez, que tout le monde soit au courant ;)",
|
"Please click on the day you will be in the plain, so that everyone gets informed ! ;)": "Veuillez cliquer sur les jours où vous serez présent dans la plaine du Forez, que tout le monde soit au courant ;)",
|
||||||
"Please enter message content: ": "Veuillez entrer le contenu du message :",
|
"Please enter message content: ": "Veuillez entrer le contenu du message :",
|
||||||
"Please enter new message content:": "Veuillez entrer le contenu du nouveau message :",
|
"Please enter new message content:": "Veuillez entrer le contenu du nouveau message :",
|
||||||
@ -534,6 +536,7 @@
|
|||||||
"Question 1": "Question 1",
|
"Question 1": "Question 1",
|
||||||
"Question 2": "Question 2",
|
"Question 2": "Question 2",
|
||||||
"Ready": "Prêt",
|
"Ready": "Prêt",
|
||||||
|
"Reason of report": "Raison du signalement",
|
||||||
"Receive notifications for the conversations you follow.": "Recevoir des notifications push pour les conversations que vous suivez",
|
"Receive notifications for the conversations you follow.": "Recevoir des notifications push pour les conversations que vous suivez",
|
||||||
"Record audio": "Faire un enregistrement audio",
|
"Record audio": "Faire un enregistrement audio",
|
||||||
"Recording...": "Enregistrement...",
|
"Recording...": "Enregistrement...",
|
||||||
@ -543,6 +546,8 @@
|
|||||||
"Remove": "Supprimer",
|
"Remove": "Supprimer",
|
||||||
"Remove selected image": "Supprimer l'image sélectionnée",
|
"Remove selected image": "Supprimer l'image sélectionnée",
|
||||||
"Replace image": "Remplacer l'image",
|
"Replace image": "Remplacer l'image",
|
||||||
|
"Report abuse": "Signaler un abus",
|
||||||
|
"Report successfully saved. Thank you for your contribution!": "Le report a bien été pris en compte. Merci pour votre contribution !",
|
||||||
"Request membership": "Demander de rejoindre le groupe",
|
"Request membership": "Demander de rejoindre le groupe",
|
||||||
"Requested": "En attente",
|
"Requested": "En attente",
|
||||||
"Respond to survey": "Répondre au sondage",
|
"Respond to survey": "Répondre au sondage",
|
||||||
@ -642,8 +647,11 @@
|
|||||||
"You can search the people you know and ask them to become your friends!": "Vous pouvez rechercher vos connaissances et les demander en amis !",
|
"You can search the people you know and ask them to become your friends!": "Vous pouvez rechercher vos connaissances et les demander en amis !",
|
||||||
"You can search the people you know and ask them to become your friends!\\n\\nThis will help you to reach them to exchange information!": "Vous pouvez rechercher vos connaissances et les demander en amis, pour entrer facilement en contact avec elles !",
|
"You can search the people you know and ask them to become your friends!\\n\\nThis will help you to reach them to exchange information!": "Vous pouvez rechercher vos connaissances et les demander en amis, pour entrer facilement en contact avec elles !",
|
||||||
"You can use this virtual directory.": "Vous pouvez utiliser ce répertoire virtuel.",
|
"You can use this virtual directory.": "Vous pouvez utiliser ce répertoire virtuel.",
|
||||||
|
"You do not have any conversation yet!": "Vous n'avez pas encore de conversation !",
|
||||||
|
"You do not have any friend yet!": "Vous n'avez pas encore d'amis sur Comunic !",
|
||||||
"You do not have any notification now.": "Vous n'avez pas de notification pour l'intant.",
|
"You do not have any notification now.": "Vous n'avez pas de notification pour l'intant.",
|
||||||
"You do not have any unread conversation yet...": "Vous n'avez aucune conversation non lue pour le moment...",
|
"You do not have any unread conversation yet...": "Vous n'avez aucune conversation non lue pour le moment...",
|
||||||
|
"You have already sent a report for this resource!": "Vous avez déjà soumis un signalement pour cette ressource !",
|
||||||
"You must accept the Terms Of Service to continue.": "Vous devez accepter les Conditions d'utilisation pour continuer.",
|
"You must accept the Terms Of Service to continue.": "Vous devez accepter les Conditions d'utilisation pour continuer.",
|
||||||
"You security questions have been successfully updated!": "Vos questions de sécurité ont été mises avec succès !",
|
"You security questions have been successfully updated!": "Vos questions de sécurité ont été mises avec succès !",
|
||||||
"You will need to restart the application to apply changes": "Vous aurez besoin de redémarrer l'application pour appliquer les changements",
|
"You will need to restart the application to apply changes": "Vous aurez besoin de redémarrer l'application pour appliquer les changements",
|
||||||
|
@ -5,7 +5,7 @@ make stable_release_split_per_abi && \
|
|||||||
mv build/app/outputs/flutter-apk/app-armeabi-v7a-stable-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-armeabi-v7a-stable-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/flutter-apk/app-arm64-v8a-stable-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-arm64-v8a-stable-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/flutter-apk/app-x86_64-stable-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-x86_64-stable-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/mapping/stable/release/mapping.txt "$DEST" && \
|
mv build/app/outputs/mapping/stableRelease/mapping.txt "$DEST" && \
|
||||||
make stable_release && \
|
make stable_release && \
|
||||||
mv build/app/outputs/flutter-apk/app-stable-release.apk "$DEST"
|
mv build/app/outputs/flutter-apk/app-stable-release.apk "$DEST"
|
||||||
|
|
||||||
|
@ -5,4 +5,4 @@ make forez_release_split_per_abi && \
|
|||||||
mv build/app/outputs/flutter-apk/app-armeabi-v7a-forez-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-armeabi-v7a-forez-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/flutter-apk/app-arm64-v8a-forez-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-arm64-v8a-forez-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/flutter-apk/app-x86_64-forez-release.apk "$DEST" && \
|
mv build/app/outputs/flutter-apk/app-x86_64-forez-release.apk "$DEST" && \
|
||||||
mv build/app/outputs/mapping/forez/release/mapping.txt "$DEST"
|
mv build/app/outputs/mapping/forezRelease/mapping.txt "$DEST"
|
1
build_comunic_ios.sh
Executable file
1
build_comunic_ios.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
flutter build ipa --flavor comunic -t lib/main_online.dart
|
1
build_forez_ios.sh
Executable file
1
build_forez_ios.sh
Executable file
@ -0,0 +1 @@
|
|||||||
|
flutter build ipa --flavor forez -t lib/forez/main_forez_online.dart
|
43
ios/Podfile
43
ios/Podfile
@ -36,5 +36,48 @@ end
|
|||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(target)
|
flutter_additional_ios_build_settings(target)
|
||||||
|
|
||||||
|
target.build_configurations.each do |config|
|
||||||
|
# You can remove unused permissions here
|
||||||
|
# for more infomation: https://github.com/BaseflowIT/flutter-permission-handler/blob/develop/permission_handler/ios/Classes/PermissionHandlerEnums.h
|
||||||
|
# e.g. when you don't need camera permission, just add 'PERMISSION_CAMERA=0'
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'$(inherited)',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.calendar
|
||||||
|
'PERMISSION_EVENTS=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.reminders
|
||||||
|
'PERMISSION_REMINDERS=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.contacts
|
||||||
|
'PERMISSION_CONTACTS=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.camera
|
||||||
|
# 'PERMISSION_CAMERA=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.microphone
|
||||||
|
# 'PERMISSION_MICROPHONE=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.speech
|
||||||
|
'PERMISSION_SPEECH_RECOGNIZER=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.photos
|
||||||
|
#'PERMISSION_PHOTOS=0'
|
||||||
|
|
||||||
|
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
|
||||||
|
'PERMISSION_LOCATION=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.notification
|
||||||
|
# 'PERMISSION_NOTIFICATIONS=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.mediaLibrary
|
||||||
|
# 'PERMISSION_MEDIA_LIBRARY=0',
|
||||||
|
|
||||||
|
## dart: PermissionGroup.sensors
|
||||||
|
'PERMISSION_SENSORS=0'
|
||||||
|
]
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -281,6 +281,6 @@ SPEC CHECKSUMS:
|
|||||||
video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1
|
video_thumbnail: c4e2a3c539e247d4de13cd545344fd2d26ffafd1
|
||||||
wakelock: b0843b2479edbf6504d8d262c2959446f35373aa
|
wakelock: b0843b2479edbf6504d8d262c2959446f35373aa
|
||||||
|
|
||||||
PODFILE CHECKSUM: f92af04f373e0b50153886c1f8a6969f509e3fc8
|
PODFILE CHECKSUM: efdcc144b284f95c85507e2c43974fc68ced9a09
|
||||||
|
|
||||||
COCOAPODS: 1.10.0
|
COCOAPODS: 1.10.0
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
6B56B0EAFAE8328410BF4F0C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F57A07BDAAD5F07639423EE8 /* Pods_Runner.framework */; };
|
6B56B0EAFAE8328410BF4F0C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F57A07BDAAD5F07639423EE8 /* Pods_Runner.framework */; };
|
||||||
8F2AEBBC26394110007DF92A /* LaunchScreenForez.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8F2AEBBA26394110007DF92A /* LaunchScreenForez.storyboard */; };
|
8F2AEBBC26394110007DF92A /* LaunchScreenForez.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8F2AEBBA26394110007DF92A /* LaunchScreenForez.storyboard */; };
|
||||||
|
8FFF7880264272F1002E5895 /* config in Resources */ = {isa = PBXBuildFile; fileRef = 8FFF787F264272F1002E5895 /* config */; };
|
||||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
|
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
|
||||||
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
|
||||||
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
|
||||||
@ -45,6 +46,8 @@
|
|||||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
|
||||||
8CF757033A070BF5F6AD7355 /* Pods-Runner.debug-comunic.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-comunic.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-comunic.xcconfig"; sourceTree = "<group>"; };
|
8CF757033A070BF5F6AD7355 /* Pods-Runner.debug-comunic.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug-comunic.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug-comunic.xcconfig"; sourceTree = "<group>"; };
|
||||||
8F2AEBBB26394110007DF92A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreenForez.storyboard; sourceTree = "<group>"; };
|
8F2AEBBB26394110007DF92A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreenForez.storyboard; sourceTree = "<group>"; };
|
||||||
|
8FEFC7EA26405694003B7DF3 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
|
8FFF787F264272F1002E5895 /* config */ = {isa = PBXFileReference; lastKnownFileType = folder; path = config; sourceTree = "<group>"; };
|
||||||
9731915131511AD49411A740 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
9731915131511AD49411A740 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||||
@ -87,6 +90,7 @@
|
|||||||
97C146E51CF9000F007C117D = {
|
97C146E51CF9000F007C117D = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
8FFF787F264272F1002E5895 /* config */,
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
@ -106,6 +110,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
8FEFC7EA26405694003B7DF3 /* Runner.entitlements */,
|
||||||
8F2AEBBA26394110007DF92A /* LaunchScreenForez.storyboard */,
|
8F2AEBBA26394110007DF92A /* LaunchScreenForez.storyboard */,
|
||||||
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */,
|
||||||
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */,
|
||||||
@ -164,6 +169,7 @@
|
|||||||
9740EEB61CF901F6004384FC /* Run Script */,
|
9740EEB61CF901F6004384FC /* Run Script */,
|
||||||
97C146EA1CF9000F007C117D /* Sources */,
|
97C146EA1CF9000F007C117D /* Sources */,
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||||
|
8FFF788226427350002E5895 /* Copy GoogleService-Info.plist to the correct location */,
|
||||||
97C146EC1CF9000F007C117D /* Resources */,
|
97C146EC1CF9000F007C117D /* Resources */,
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
@ -189,7 +195,7 @@
|
|||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
CreatedOnToolsVersion = 7.3.1;
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
DevelopmentTeam = A9JXUMT7RC;
|
DevelopmentTeam = QRU542F2B8;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -218,6 +224,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
|
||||||
|
8FFF7880264272F1002E5895 /* config in Resources */,
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
|
||||||
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
|
9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
|
||||||
@ -265,6 +272,24 @@
|
|||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||||
};
|
};
|
||||||
|
8FFF788226427350002E5895 /* Copy GoogleService-Info.plist to the correct location */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
);
|
||||||
|
name = "Copy GoogleService-Info.plist to the correct location";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "setopt KSH_ARRAYS BASH_REMATCH\nenvironment=\"default\"\n\n# Regex to extract the scheme name from the Build Configuration\n# We have named our Build Configurations as Debug-dev, Debug-prod etc.\n# Here, dev and prod are the scheme names. This kind of naming is required by Flutter for flavors to work.\n# We are using the $CONFIGURATION variable available in the XCode build environment to extract \n# the environment (or flavor)\n# For eg.\n# If CONFIGURATION=\"Debug-prod\", then environment will get set to \"prod\".\nif [[ $CONFIGURATION =~ -([^-]*)$ ]]; then\nenvironment=${BASH_REMATCH[1]}\nfi\n\necho $environment\n\n# Name and path of the resource we're copying\nGOOGLESERVICE_INFO_PLIST=GoogleService-Info.plist\nGOOGLESERVICE_INFO_FILE=${PROJECT_DIR}/config/${environment}/${GOOGLESERVICE_INFO_PLIST}\n\n# Make sure GoogleService-Info.plist exists\necho \"Looking for ${GOOGLESERVICE_INFO_PLIST} in ${GOOGLESERVICE_INFO_FILE}\"\nif [ ! -f $GOOGLESERVICE_INFO_FILE ]\nthen\necho \"No GoogleService-Info.plist found. Please ensure it's in the proper directory.\"\nexit 1\nfi\n\n# Get a reference to the destination location for the GoogleService-Info.plist\n# This is the default location where Firebase init code expects to find GoogleServices-Info.plist file\nPLIST_DESTINATION=${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app\necho \"Will copy ${GOOGLESERVICE_INFO_PLIST} to final destination: ${PLIST_DESTINATION}\"\n\n# Copy over the prod GoogleService-Info.plist for Release builds\ncp \"${GOOGLESERVICE_INFO_FILE}\" \"${PLIST_DESTINATION}\"\n# unsetopt KSH_ARRAYS\n";
|
||||||
|
};
|
||||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@ -277,7 +302,7 @@
|
|||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
shellPath = /bin/sh;
|
shellPath = /bin/sh;
|
||||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
|
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||||
};
|
};
|
||||||
C9EE070942D44B728369915C /* [CP] Embed Pods Frameworks */ = {
|
C9EE070942D44B728369915C /* [CP] Embed Pods Frameworks */ = {
|
||||||
isa = PBXShellScriptBuildPhase;
|
isa = PBXShellScriptBuildPhase;
|
||||||
@ -456,8 +481,9 @@
|
|||||||
APP_DISPLAY_NAME = Comunic;
|
APP_DISPLAY_NAME = Comunic;
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = S8QB4VV633;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -469,7 +495,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.comunic;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.comunic;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@ -535,8 +561,9 @@
|
|||||||
APP_DISPLAY_NAME = "#Forez";
|
APP_DISPLAY_NAME = "#Forez";
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = A9JXUMT7RC;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -548,7 +575,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.forez;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.forez;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@ -608,8 +635,9 @@
|
|||||||
APP_DISPLAY_NAME = "#Forez";
|
APP_DISPLAY_NAME = "#Forez";
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = A9JXUMT7RC;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -621,7 +649,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.forez;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.forez;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@ -681,8 +709,9 @@
|
|||||||
APP_DISPLAY_NAME = "#Forez";
|
APP_DISPLAY_NAME = "#Forez";
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreenForez;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-forez";
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = S8QB4VV633;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -694,7 +723,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.forez;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.forez;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@ -807,8 +836,9 @@
|
|||||||
APP_DISPLAY_NAME = Comunic;
|
APP_DISPLAY_NAME = Comunic;
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = A9JXUMT7RC;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -820,7 +850,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.comunic;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.comunic;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
@ -833,8 +863,9 @@
|
|||||||
APP_DISPLAY_NAME = Comunic;
|
APP_DISPLAY_NAME = Comunic;
|
||||||
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
APP_LAUNCH_STORYBOARD_NAME = LaunchScreen;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
DEVELOPMENT_TEAM = A9JXUMT7RC;
|
DEVELOPMENT_TEAM = QRU542F2B8;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
FRAMEWORK_SEARCH_PATHS = (
|
FRAMEWORK_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
@ -846,7 +877,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/Flutter",
|
"$(PROJECT_DIR)/Flutter",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = org.communiquons.comunic;
|
PRODUCT_BUNDLE_IDENTIFIER = org.PierreHubert.comunic;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
VERSIONING_SYSTEM = "apple-generic";
|
VERSIONING_SYSTEM = "apple-generic";
|
||||||
};
|
};
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 80 KiB |
@ -1,122 +1,122 @@
|
|||||||
{
|
{
|
||||||
"images" : [
|
"images" : [
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-20x20@2x.png",
|
"filename" : "Icon-App-20x20@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-20x20@3x.png",
|
"filename" : "Icon-App-20x20@3x.png",
|
||||||
"scale" : "3x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"filename" : "Icon-App-29x29@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-29x29@2x.png",
|
"filename" : "Icon-App-29x29@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-29x29@3x.png",
|
"filename" : "Icon-App-29x29@3x.png",
|
||||||
"scale" : "3x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-40x40@2x.png",
|
"filename" : "Icon-App-40x40@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-40x40@3x.png",
|
"filename" : "Icon-App-40x40@3x.png",
|
||||||
"scale" : "3x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
|
||||||
"filename" : "Icon-App-60x60@2x.png",
|
"filename" : "Icon-App-60x60@2x.png",
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "60x60",
|
|
||||||
"idiom" : "iphone",
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "60x60"
|
||||||
|
},
|
||||||
|
{
|
||||||
"filename" : "Icon-App-60x60@3x.png",
|
"filename" : "Icon-App-60x60@3x.png",
|
||||||
"scale" : "3x"
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "60x60"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-20x20@1x.png",
|
"filename" : "Icon-App-20x20@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "20x20",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-20x20@2x.png",
|
"filename" : "Icon-App-20x20@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "20x20"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-29x29@1x.png",
|
"filename" : "Icon-App-29x29@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "29x29",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-29x29@2x.png",
|
"filename" : "Icon-App-29x29@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "29x29"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-40x40@1x.png",
|
"filename" : "Icon-App-40x40@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "40x40",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-40x40@2x.png",
|
"filename" : "Icon-App-40x40@2x.png",
|
||||||
"scale" : "2x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "40x40"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-76x76@1x.png",
|
"filename" : "Icon-App-76x76@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "76x76"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "76x76",
|
|
||||||
"idiom" : "ipad",
|
|
||||||
"filename" : "Icon-App-76x76@2x.png",
|
"filename" : "Icon-App-76x76@2x.png",
|
||||||
"scale" : "2x"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"size" : "83.5x83.5",
|
|
||||||
"idiom" : "ipad",
|
"idiom" : "ipad",
|
||||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
"scale" : "2x",
|
||||||
"scale" : "2x"
|
"size" : "76x76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "83.5x83.5"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"size" : "1024x1024",
|
|
||||||
"idiom" : "ios-marketing",
|
|
||||||
"filename" : "Icon-App-1024x1024@1x.png",
|
"filename" : "Icon-App-1024x1024@1x.png",
|
||||||
"scale" : "1x"
|
"idiom" : "ios-marketing",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "1024x1024"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"info" : {
|
"info" : {
|
||||||
"version" : 1,
|
"author" : "xcode",
|
||||||
"author" : "xcode"
|
"version" : 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 53 KiB |
@ -66,5 +66,11 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
|
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||||
|
<string>This permission is not needed by the app, but it is required by an underlying API. If you see this dialog, contact us.</string>
|
||||||
|
<key>NSAppleMusicUsageDescription</key>
|
||||||
|
<string>This permission is not needed by the app, but it is required by an underlying API. If you see this dialog, contact us.</string>
|
||||||
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
|
<string>This permission is not needed by the app, but it is required by an underlying API. If you see this dialog, contact us.</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
8
ios/Runner/Runner.entitlements
Normal file
8
ios/Runner/Runner.entitlements
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>aps-environment</key>
|
||||||
|
<string>development</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
34
ios/config/comunic/GoogleService-Info.plist
Normal file
34
ios/config/comunic/GoogleService-Info.plist
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CLIENT_ID</key>
|
||||||
|
<string>1007877315904-umuhjlq7qfcdn8f24kjddhpmlb67gvpd.apps.googleusercontent.com</string>
|
||||||
|
<key>REVERSED_CLIENT_ID</key>
|
||||||
|
<string>com.googleusercontent.apps.1007877315904-umuhjlq7qfcdn8f24kjddhpmlb67gvpd</string>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyBzcEJVIHvHl-viG19qR3LFhb6aYj5EZXM</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>1007877315904</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>org.PierreHubert.comunic</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>comunic-ae92c</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>comunic-ae92c.appspot.com</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:1007877315904:ios:469f6c61859712260aeea5</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
36
ios/config/forez/GoogleService-Info.plist
Normal file
36
ios/config/forez/GoogleService-Info.plist
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CLIENT_ID</key>
|
||||||
|
<string>500630888942-0b42osg6gpr5tnr8s49uvlstg1bil1be.apps.googleusercontent.com</string>
|
||||||
|
<key>REVERSED_CLIENT_ID</key>
|
||||||
|
<string>com.googleusercontent.apps.500630888942-0b42osg6gpr5tnr8s49uvlstg1bil1be</string>
|
||||||
|
<key>API_KEY</key>
|
||||||
|
<string>AIzaSyBuhS3BM7Ql6sQ1EPghKiLaLjh_78pT9-k</string>
|
||||||
|
<key>GCM_SENDER_ID</key>
|
||||||
|
<string>500630888942</string>
|
||||||
|
<key>PLIST_VERSION</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>BUNDLE_ID</key>
|
||||||
|
<string>org.PierreHubert.forez</string>
|
||||||
|
<key>PROJECT_ID</key>
|
||||||
|
<string>forez-1b859</string>
|
||||||
|
<key>STORAGE_BUCKET</key>
|
||||||
|
<string>forez-1b859.appspot.com</string>
|
||||||
|
<key>IS_ADS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_ANALYTICS_ENABLED</key>
|
||||||
|
<false></false>
|
||||||
|
<key>IS_APPINVITE_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_GCM_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>IS_SIGNIN_ENABLED</key>
|
||||||
|
<true></true>
|
||||||
|
<key>GOOGLE_APP_ID</key>
|
||||||
|
<string>1:500630888942:ios:4bac527bf743b4b5d02eff</string>
|
||||||
|
<key>DATABASE_URL</key>
|
||||||
|
<string>https://forez-1b859.firebaseio.com</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
28
lib/enums/report_target_type.dart
Normal file
28
lib/enums/report_target_type.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/// What kind of content that can be reported
|
||||||
|
enum ReportTargetType {
|
||||||
|
Post,
|
||||||
|
Comment,
|
||||||
|
Conversation,
|
||||||
|
ConversationMessage,
|
||||||
|
User,
|
||||||
|
Group
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ReportTargetExt on ReportTargetType {
|
||||||
|
String get apiId {
|
||||||
|
switch (this) {
|
||||||
|
case ReportTargetType.Post:
|
||||||
|
return "post";
|
||||||
|
case ReportTargetType.Comment:
|
||||||
|
return "comment";
|
||||||
|
case ReportTargetType.Conversation:
|
||||||
|
return "conversation";
|
||||||
|
case ReportTargetType.ConversationMessage:
|
||||||
|
return "conversation_message";
|
||||||
|
case ReportTargetType.User:
|
||||||
|
return "user";
|
||||||
|
case ReportTargetType.Group:
|
||||||
|
return "group";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ import 'package:comunic/models/advanced_group_info.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
AdvancedGroupInfo _forezGroup;
|
AdvancedGroupInfo? _forezGroup;
|
||||||
|
|
||||||
class ForezGroupHelper {
|
class ForezGroupHelper {
|
||||||
static Future<void> setId(int groupID) async {
|
static Future<void> setId(int groupID) async {
|
||||||
@ -16,7 +16,7 @@ class ForezGroupHelper {
|
|||||||
.setInt(PreferencesKeyList.FOREZ_GROUP, groupID);
|
.setInt(PreferencesKeyList.FOREZ_GROUP, groupID);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<int> getId() async {
|
static Future<int?> getId() async {
|
||||||
return (await PreferencesHelper.getInstance())
|
return (await PreferencesHelper.getInstance())
|
||||||
.getInt(PreferencesKeyList.FOREZ_GROUP);
|
.getInt(PreferencesKeyList.FOREZ_GROUP);
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ class ForezGroupHelper {
|
|||||||
_forezGroup = res.info;
|
_forezGroup = res.info;
|
||||||
}
|
}
|
||||||
|
|
||||||
static AdvancedGroupInfo getGroup() => _forezGroup;
|
static AdvancedGroupInfo? getGroup() => _forezGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
AdvancedGroupInfo get forezGroup => ForezGroupHelper.getGroup();
|
AdvancedGroupInfo? get forezGroup => ForezGroupHelper.getGroup();
|
||||||
|
@ -11,10 +11,10 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class ForezConfig extends Config {
|
class ForezConfig extends Config {
|
||||||
ForezConfig({
|
ForezConfig({
|
||||||
@required String apiServerName,
|
required String apiServerName,
|
||||||
@required String apiServerUri,
|
required String apiServerUri,
|
||||||
@required bool apiServerSecure,
|
required bool apiServerSecure,
|
||||||
@required String clientName,
|
required String clientName,
|
||||||
}) : super(
|
}) : super(
|
||||||
apiServerName: apiServerName,
|
apiServerName: apiServerName,
|
||||||
apiServerUri: apiServerUri,
|
apiServerUri: apiServerUri,
|
||||||
|
@ -11,7 +11,7 @@ import 'package:comunic/models/config.dart';
|
|||||||
/// Fix HTTPS issue
|
/// Fix HTTPS issue
|
||||||
class MyHttpOverride extends HttpOverrides {
|
class MyHttpOverride extends HttpOverrides {
|
||||||
@override
|
@override
|
||||||
HttpClient createHttpClient(SecurityContext context) {
|
HttpClient createHttpClient(SecurityContext? context) {
|
||||||
return super.createHttpClient(context)
|
return super.createHttpClient(context)
|
||||||
..badCertificateCallback = (cert, host, port) {
|
..badCertificateCallback = (cert, host, port) {
|
||||||
return host == "devweb.local"; // Forcefully trust local website
|
return host == "devweb.local"; // Forcefully trust local website
|
||||||
|
@ -29,7 +29,7 @@ List<Widget> buildTour(TourRouteState state) {
|
|||||||
msgTwo: tr("Let's first join a Forez group!"),
|
msgTwo: tr("Let's first join a Forez group!"),
|
||||||
),
|
),
|
||||||
JoinForezGroupPane(
|
JoinForezGroupPane(
|
||||||
key: state.pubKeys[_JOIN_GROUP_KEY_ID],
|
key: state.pubKeys[_JOIN_GROUP_KEY_ID] as GlobalKey<JoinGroupPaneBodyState>?,
|
||||||
onUpdated: () => state.rebuild(),
|
onUpdated: () => state.rebuild(),
|
||||||
),
|
),
|
||||||
FirstTourPane(
|
FirstTourPane(
|
||||||
@ -51,7 +51,7 @@ List<Widget> buildTour(TourRouteState state) {
|
|||||||
// Forez specific features
|
// Forez specific features
|
||||||
PresentationPane(
|
PresentationPane(
|
||||||
icon: Icons.calendar_today,
|
icon: Icons.calendar_today,
|
||||||
title: tr("Presence in Forez"),
|
title: tr("Presence in Forez")!,
|
||||||
text: tr(
|
text: tr(
|
||||||
"Easily specify the days you are in Forez plain, so that everyone can know it!"),
|
"Easily specify the days you are in Forez plain, so that everyone can know it!"),
|
||||||
actionTitle: tr("Do it now!"),
|
actionTitle: tr("Do it now!"),
|
||||||
@ -62,7 +62,7 @@ List<Widget> buildTour(TourRouteState state) {
|
|||||||
// Chat pane
|
// Chat pane
|
||||||
PresentationPane(
|
PresentationPane(
|
||||||
icon: Icons.question_answer,
|
icon: Icons.question_answer,
|
||||||
title: tr("Conversations"),
|
title: tr("Conversations")!,
|
||||||
text: tr(
|
text: tr(
|
||||||
"#Forez now integrates the conversation system of Comunic, so you have access both to public and private conversations!"),
|
"#Forez now integrates the conversation system of Comunic, so you have access both to public and private conversations!"),
|
||||||
),
|
),
|
||||||
|
@ -16,17 +16,17 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class JoinForezGroupPane extends PresentationPane {
|
class JoinForezGroupPane extends PresentationPane {
|
||||||
JoinForezGroupPane({
|
JoinForezGroupPane({
|
||||||
@required Function() onUpdated,
|
required Function() onUpdated,
|
||||||
@required GlobalKey<JoinGroupPaneBodyState> key,
|
required GlobalKey<JoinGroupPaneBodyState>? key,
|
||||||
}) : super(
|
}) : super(
|
||||||
icon: Icons.login,
|
icon: Icons.login,
|
||||||
title: tr("Join a Forez group"),
|
title: tr("Join a Forez group")!,
|
||||||
child: (c) => _JoinGroupPaneBody(
|
child: (c) => _JoinGroupPaneBody(
|
||||||
key: key,
|
key: key,
|
||||||
onUpdated: onUpdated,
|
onUpdated: onUpdated,
|
||||||
),
|
),
|
||||||
canGoNext: key?.currentState?.canGoNext ?? false,
|
canGoNext: key?.currentState?.canGoNext ?? false,
|
||||||
onTapNext: (c) => key.currentState.validateChoice(),
|
onTapNext: (c) => key!.currentState!.validateChoice(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,10 +34,9 @@ class _JoinGroupPaneBody extends StatefulWidget {
|
|||||||
final Function() onUpdated;
|
final Function() onUpdated;
|
||||||
|
|
||||||
const _JoinGroupPaneBody({
|
const _JoinGroupPaneBody({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.onUpdated,
|
required this.onUpdated,
|
||||||
}) : assert(onUpdated != null),
|
}) : super(key: key);
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
JoinGroupPaneBodyState createState() => JoinGroupPaneBodyState();
|
JoinGroupPaneBodyState createState() => JoinGroupPaneBodyState();
|
||||||
@ -46,10 +45,10 @@ class _JoinGroupPaneBody extends StatefulWidget {
|
|||||||
class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
|
class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
|
||||||
final _key = GlobalKey<AsyncScreenWidgetState>();
|
final _key = GlobalKey<AsyncScreenWidgetState>();
|
||||||
|
|
||||||
List<Group> _groups;
|
late List<Group> _groups;
|
||||||
int _currChoice;
|
int? _currChoice;
|
||||||
|
|
||||||
bool get canGoNext => _currChoice != null && _currChoice > 0;
|
bool get canGoNext => _currChoice != null && _currChoice! > 0;
|
||||||
|
|
||||||
Group get _currGroup => _groups.firstWhere((e) => e.id == _currChoice);
|
Group get _currGroup => _groups.firstWhere((e) => e.id == _currChoice);
|
||||||
|
|
||||||
@ -65,17 +64,17 @@ class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
|
|||||||
key: _key,
|
key: _key,
|
||||||
onReload: _load,
|
onReload: _load,
|
||||||
onBuild: onBuild,
|
onBuild: onBuild,
|
||||||
errorMessage: tr("Failed to load the list of Forez groups!"));
|
errorMessage: tr("Failed to load the list of Forez groups!")!);
|
||||||
|
|
||||||
Widget onBuild() => ConstrainedBox(
|
Widget onBuild() => ConstrainedBox(
|
||||||
constraints: BoxConstraints(maxWidth: 300),
|
constraints: BoxConstraints(maxWidth: 300),
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Text(tr("Please choose now the Forez group you want to join...")),
|
Text(tr("Please choose now the Forez group you want to join...")!),
|
||||||
]..addAll(_groups.map((e) => RadioListTile(
|
]..addAll(_groups.map((e) => RadioListTile(
|
||||||
value: e.id,
|
value: e.id,
|
||||||
groupValue: _currChoice,
|
groupValue: _currChoice,
|
||||||
onChanged: (v) => setState(() => _currChoice = _currChoice),
|
onChanged: (dynamic v) => setState(() => _currChoice = e.id),
|
||||||
title: Text(e.name),
|
title: Text(e.name),
|
||||||
subtitle: Text(e.membershipText),
|
subtitle: Text(e.membershipText),
|
||||||
))),
|
))),
|
||||||
@ -112,7 +111,7 @@ class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
|
|||||||
await alert(context,
|
await alert(context,
|
||||||
"${tr("You can not access this group yet, please wait for a member of the group to accept your request.")}\n${tr("Hopefully this will not be too long.")}\n${tr("Please check back soon!")}");
|
"${tr("You can not access this group yet, please wait for a member of the group to accept your request.")}\n${tr("Hopefully this will not be too long.")}\n${tr("Please check back soon!")}");
|
||||||
|
|
||||||
_key.currentState.refresh();
|
_key.currentState!.refresh();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -121,8 +120,8 @@ class JoinGroupPaneBodyState extends State<_JoinGroupPaneBody> {
|
|||||||
return true;
|
return true;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
logError(e, s);
|
logError(e, s);
|
||||||
snack(context, tr("Failed to register to group!"));
|
snack(context, tr("Failed to register to group!")!);
|
||||||
_key.currentState.refresh();
|
_key.currentState!.refresh();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import 'package:comunic/utils/conversations_utils.dart';
|
|||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:comunic/utils/ui_utils.dart';
|
import 'package:comunic/utils/ui_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
/// Show information about a Forez member
|
/// Show information about a Forez member
|
||||||
///
|
///
|
||||||
@ -24,10 +24,9 @@ class ForezMemberProfileRoute extends StatefulWidget {
|
|||||||
final int userID;
|
final int userID;
|
||||||
|
|
||||||
const ForezMemberProfileRoute({
|
const ForezMemberProfileRoute({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
}) : assert(userID != null),
|
}) : super(key: key);
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ForezMemberProfileRouteState createState() =>
|
_ForezMemberProfileRouteState createState() =>
|
||||||
@ -39,13 +38,14 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
|
|
||||||
final _key = GlobalKey<AsyncScreenWidgetState>();
|
final _key = GlobalKey<AsyncScreenWidgetState>();
|
||||||
|
|
||||||
AdvancedUserInfo _user;
|
late AdvancedUserInfo _user;
|
||||||
PresenceSet _presence;
|
late PresenceSet _presence;
|
||||||
|
|
||||||
Future<void> _load() async {
|
Future<void> _load() async {
|
||||||
_user = await ForezGroupsHelper.getMemberInfo(forezGroup.id, widget.userID);
|
_user =
|
||||||
|
await ForezGroupsHelper.getMemberInfo(forezGroup!.id, widget.userID);
|
||||||
_presence =
|
_presence =
|
||||||
await ForezPresenceHelper.getForUser(forezGroup.id, widget.userID);
|
await ForezPresenceHelper.getForUser(forezGroup!.id, widget.userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -56,25 +56,25 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
loadingWidget: _buildLoading(),
|
loadingWidget: _buildLoading(),
|
||||||
errorWidget: _buildError(),
|
errorWidget: _buildError(),
|
||||||
errorMessage: tr(
|
errorMessage: tr(
|
||||||
"Failed to load user information, maybe it is not a Forez member yet?"));
|
"Failed to load user information, maybe it is not a Forez member yet?")!);
|
||||||
|
|
||||||
Widget _buildLoading() => Scaffold(
|
Widget _buildLoading() => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(tr("Loading...")),
|
title: Text(tr("Loading...")!),
|
||||||
),
|
),
|
||||||
body: buildCenteredProgressBar(),
|
body: buildCenteredProgressBar(),
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildError() => Scaffold(
|
Widget _buildError() => Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(tr("Error")),
|
title: Text(tr("Error")!),
|
||||||
),
|
),
|
||||||
body: buildErrorCard(
|
body: buildErrorCard(
|
||||||
tr("Failed to load user information, maybe it is not a Forez member yet?"),
|
tr("Failed to load user information, maybe it is not a Forez member yet?"),
|
||||||
actions: [
|
actions: [
|
||||||
MaterialButton(
|
MaterialButton(
|
||||||
onPressed: () => _key.currentState.refresh(),
|
onPressed: () => _key.currentState!.refresh(),
|
||||||
child: Text(tr("Try again")),
|
child: Text(tr("Try again")!),
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
)
|
)
|
||||||
]),
|
]),
|
||||||
@ -97,9 +97,7 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
background: Stack(
|
background: Stack(
|
||||||
fit: StackFit.expand,
|
fit: StackFit.expand,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
_user.accountImageURL == null
|
CachedNetworkImage(
|
||||||
? Container()
|
|
||||||
: CachedNetworkImage(
|
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
imageUrl: _user.accountImageURL,
|
imageUrl: _user.accountImageURL,
|
||||||
height: _appBarHeight,
|
height: _appBarHeight,
|
||||||
@ -135,7 +133,7 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
: ListTile(
|
: ListTile(
|
||||||
leading: Icon(Icons.note),
|
leading: Icon(Icons.note),
|
||||||
title: TextWidget(content: DisplayedString(_user.publicNote)),
|
title: TextWidget(content: DisplayedString(_user.publicNote)),
|
||||||
subtitle: Text(tr("Note")),
|
subtitle: Text(tr("Note")!),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Email address
|
// Email address
|
||||||
@ -143,9 +141,9 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
? Container()
|
? Container()
|
||||||
: ListTile(
|
: ListTile(
|
||||||
leading: Icon(Icons.email),
|
leading: Icon(Icons.email),
|
||||||
title: Text(_user.emailAddress),
|
title: Text(_user.emailAddress!),
|
||||||
subtitle: Text(tr("Email address")),
|
subtitle: Text(tr("Email address")!),
|
||||||
trailing: CopyIcon(_user.emailAddress),
|
trailing: CopyIcon(_user.emailAddress!),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Location
|
// Location
|
||||||
@ -153,9 +151,9 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
? Container()
|
? Container()
|
||||||
: ListTile(
|
: ListTile(
|
||||||
leading: Icon(Icons.location_on),
|
leading: Icon(Icons.location_on),
|
||||||
title: Text(_user.location),
|
title: Text(_user.location!),
|
||||||
subtitle: Text(tr("Location")),
|
subtitle: Text(tr("Location")!),
|
||||||
trailing: CopyIcon(_user.location),
|
trailing: CopyIcon(_user.location!),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Website
|
// Website
|
||||||
@ -164,20 +162,20 @@ class _ForezMemberProfileRouteState extends State<ForezMemberProfileRoute> {
|
|||||||
: ListTile(
|
: ListTile(
|
||||||
leading: Icon(Icons.link),
|
leading: Icon(Icons.link),
|
||||||
title: Text(_user.personalWebsite),
|
title: Text(_user.personalWebsite),
|
||||||
subtitle: Text(tr("Website")),
|
subtitle: Text(tr("Website")!),
|
||||||
trailing: IconButton(
|
trailing: IconButton(
|
||||||
icon: Icon(Icons.open_in_new),
|
icon: Icon(Icons.open_in_new),
|
||||||
onPressed: () => launch(_user.personalWebsite),
|
onPressed: () => launchUrlString(_user.personalWebsite),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
Divider(),
|
Divider(),
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: Icon(Icons.calendar_today),
|
leading: Icon(Icons.calendar_today),
|
||||||
title: Text(tr("Presence in Forez")),
|
title: Text(tr("Presence in Forez")!),
|
||||||
subtitle: Text(_presence.containsDate(DateTime.now())
|
subtitle: Text(_presence.containsDate(DateTime.now())
|
||||||
? tr("Present today")
|
? tr("Present today")!
|
||||||
: tr("Absent")),
|
: tr("Absent")!),
|
||||||
),
|
),
|
||||||
PresenceCalendarWidget(presenceSet: _presence),
|
PresenceCalendarWidget(presenceSet: _presence),
|
||||||
Divider(),
|
Divider(),
|
||||||
|
@ -9,6 +9,7 @@ import 'package:comunic/ui/routes/main_route/page_info.dart';
|
|||||||
import 'package:comunic/ui/screens/conversations_list_screen.dart';
|
import 'package:comunic/ui/screens/conversations_list_screen.dart';
|
||||||
import 'package:comunic/ui/screens/group_sections/forez_presence_section.dart';
|
import 'package:comunic/ui/screens/group_sections/forez_presence_section.dart';
|
||||||
import 'package:comunic/ui/screens/group_sections/group_posts_section.dart';
|
import 'package:comunic/ui/screens/group_sections/group_posts_section.dart';
|
||||||
|
import 'package:comunic/ui/widgets/banner_widget.dart';
|
||||||
import 'package:comunic/ui/widgets/safe_state.dart';
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
||||||
import 'package:comunic/ui/widgets/status_widget.dart';
|
import 'package:comunic/ui/widgets/status_widget.dart';
|
||||||
import 'package:comunic/ui/widgets/tab_transition_widget.dart';
|
import 'package:comunic/ui/widgets/tab_transition_widget.dart';
|
||||||
@ -20,7 +21,7 @@ import 'package:flutter/material.dart';
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class ForezRoute extends StatefulWidget implements MainRoute {
|
class ForezRoute extends StatefulWidget implements MainRoute {
|
||||||
const ForezRoute({Key key}) : super(key: key);
|
const ForezRoute({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<StatefulWidget> createState() => _MainRouteState();
|
State<StatefulWidget> createState() => _MainRouteState();
|
||||||
@ -39,7 +40,7 @@ class _MainRouteState extends MainController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (forezGroup == null) return Text(tr("Missing Forez group!"));
|
if (forezGroup == null) return Text(tr("Missing Forez group!")!);
|
||||||
|
|
||||||
return StatusWidget(
|
return StatusWidget(
|
||||||
child: (c) => SafeArea(
|
child: (c) => SafeArea(
|
||||||
@ -66,11 +67,11 @@ class _MainRouteState extends MainController {
|
|||||||
@override
|
@override
|
||||||
void openConversation(Conversation conv, {fullScreen: false}) {
|
void openConversation(Conversation conv, {fullScreen: false}) {
|
||||||
// Forcefully open conversations in a "normal" way (do not display groups)
|
// Forcefully open conversations in a "normal" way (do not display groups)
|
||||||
openConversationById(conv.id, fullScreen: fullScreen);
|
openConversationById(conv.id!, fullScreen: fullScreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void openGroup(int groupID, {int conversationID}) => _unsupportedFeature();
|
void openGroup(int groupID, {int? conversationID}) => _unsupportedFeature();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void openUserPage(int userID) => pushPage(PageInfo(
|
void openUserPage(int userID) => pushPage(PageInfo(
|
||||||
@ -91,7 +92,7 @@ class _MainRouteState extends MainController {
|
|||||||
enum _PopupMenuItems { ACTION_SETTINGS, ACTION_SIGN_OUT }
|
enum _PopupMenuItems { ACTION_SETTINGS, ACTION_SIGN_OUT }
|
||||||
|
|
||||||
class ForezRouteBody extends StatefulWidget {
|
class ForezRouteBody extends StatefulWidget {
|
||||||
ForezRouteBody({Key key}) : super(key: key);
|
ForezRouteBody({Key? key}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_ForezRouteBodyState createState() => _ForezRouteBodyState();
|
_ForezRouteBodyState createState() => _ForezRouteBodyState();
|
||||||
@ -111,11 +112,16 @@ class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
|
|||||||
length: _tabs.length,
|
length: _tabs.length,
|
||||||
child: Scaffold(
|
child: Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(forezGroup.name),
|
title: Text(forezGroup!.name),
|
||||||
actions: <Widget>[_buildPopupMenuButton()],
|
actions: <Widget>[_buildPopupMenuButton()],
|
||||||
bottom: TabBar(tabs: _tabs),
|
bottom: TabBar(tabs: _tabs),
|
||||||
),
|
),
|
||||||
body: TabBarView(children: _tabsPages),
|
body: Column(
|
||||||
|
children: [
|
||||||
|
BannerWidget(),
|
||||||
|
Expanded(child: TabBarView(children: _tabsPages)),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -123,11 +129,11 @@ class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
|
|||||||
Widget _buildPopupMenuButton() => PopupMenuButton<_PopupMenuItems>(
|
Widget _buildPopupMenuButton() => PopupMenuButton<_PopupMenuItems>(
|
||||||
itemBuilder: (c) => [
|
itemBuilder: (c) => [
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(tr("Settings")),
|
child: Text(tr("Settings")!),
|
||||||
value: _PopupMenuItems.ACTION_SETTINGS,
|
value: _PopupMenuItems.ACTION_SETTINGS,
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
child: Text(tr("Sign out")),
|
child: Text(tr("Sign out")!),
|
||||||
value: _PopupMenuItems.ACTION_SIGN_OUT,
|
value: _PopupMenuItems.ACTION_SIGN_OUT,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -137,10 +143,10 @@ class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
|
|||||||
void _onMenuSelection(_PopupMenuItems value) {
|
void _onMenuSelection(_PopupMenuItems value) {
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case _PopupMenuItems.ACTION_SETTINGS:
|
case _PopupMenuItems.ACTION_SETTINGS:
|
||||||
MainController.of(context).openSettings();
|
MainController.of(context)!.openSettings();
|
||||||
break;
|
break;
|
||||||
case _PopupMenuItems.ACTION_SIGN_OUT:
|
case _PopupMenuItems.ACTION_SIGN_OUT:
|
||||||
MainController.of(context).requestLogout();
|
MainController.of(context)!.requestLogout();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,29 +155,29 @@ class _ForezRouteBodyState extends SafeState<ForezRouteBody> {
|
|||||||
// Posts tab
|
// Posts tab
|
||||||
_Tab(
|
_Tab(
|
||||||
icon: Icons.auto_stories,
|
icon: Icons.auto_stories,
|
||||||
title: tr("Posts"),
|
title: tr("Posts")!,
|
||||||
widget: () => GroupPostsSection(group: forezGroup),
|
widget: () => GroupPostsSection(group: forezGroup!),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Presence tab
|
// Presence tab
|
||||||
_Tab(
|
_Tab(
|
||||||
icon: Icons.calendar_today,
|
icon: Icons.calendar_today,
|
||||||
title: tr("Presence"),
|
title: tr("Presence")!,
|
||||||
widget: () => ForezPresenceSection(groupID: forezGroup.id),
|
widget: () => ForezPresenceSection(groupID: forezGroup!.id),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Conversations tab
|
// Conversations tab
|
||||||
_Tab(
|
_Tab(
|
||||||
icon: Icons.question_answer,
|
icon: Icons.question_answer,
|
||||||
title: tr("Conversations"),
|
title: tr("Conversations")!,
|
||||||
widget: () => ConversationsListScreen(),
|
widget: () => ConversationsListScreen(),
|
||||||
isUnread: (c) => StatusWidgetState.of(c).unreadConversations > 0,
|
isUnread: (c) => StatusWidgetState.of(c)!.unreadConversations! > 0,
|
||||||
),
|
),
|
||||||
|
|
||||||
// Directory tab
|
// Directory tab
|
||||||
_Tab(
|
_Tab(
|
||||||
icon: Icons.import_contacts,
|
icon: Icons.import_contacts,
|
||||||
title: tr("Directory"),
|
title: tr("Directory")!,
|
||||||
widget: () => ForezDirectoryScreen(),
|
widget: () => ForezDirectoryScreen(),
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
@ -197,14 +203,12 @@ class _Tab {
|
|||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String title;
|
final String title;
|
||||||
final Widget Function() widget;
|
final Widget Function() widget;
|
||||||
final bool Function(BuildContext) isUnread;
|
final bool Function(BuildContext)? isUnread;
|
||||||
|
|
||||||
const _Tab({
|
const _Tab({
|
||||||
@required this.icon,
|
required this.icon,
|
||||||
@required this.title,
|
required this.title,
|
||||||
@required this.widget,
|
required this.widget,
|
||||||
this.isUnread,
|
this.isUnread,
|
||||||
}) : assert(icon != null),
|
});
|
||||||
assert(title != null),
|
|
||||||
assert(widget != null);
|
|
||||||
}
|
}
|
||||||
|
@ -7,18 +7,18 @@ import 'package:flutter/material.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
Future<User> searchUser(BuildContext context, UsersList users) async {
|
Future<User?> searchUser(BuildContext context, UsersList users) async {
|
||||||
return await showSearch<User>(
|
return await showSearch<User?>(
|
||||||
context: context, delegate: _SearchDelegate(users));
|
context: context, delegate: _SearchDelegate(users));
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SearchDelegate extends SearchDelegate<User> {
|
class _SearchDelegate extends SearchDelegate<User?> {
|
||||||
final UsersList _usersList;
|
final UsersList _usersList;
|
||||||
|
|
||||||
_SearchDelegate(this._usersList) : assert(_usersList != null);
|
_SearchDelegate(this._usersList);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Widget> buildActions(BuildContext context) => null;
|
List<Widget>? buildActions(BuildContext context) => null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildLeading(BuildContext context) => IconButton(
|
Widget buildLeading(BuildContext context) => IconButton(
|
||||||
@ -28,7 +28,7 @@ class _SearchDelegate extends SearchDelegate<User> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget buildSuggestions(BuildContext context) {
|
Widget buildSuggestions(BuildContext context) {
|
||||||
final list = _usersList
|
final List<User> list = _usersList
|
||||||
.where((element) =>
|
.where((element) =>
|
||||||
element.fullName.toLowerCase().contains(query.toLowerCase()))
|
element.fullName.toLowerCase().contains(query.toLowerCase()))
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -35,11 +35,11 @@ class ForezDirectoryScreen extends StatefulWidget {
|
|||||||
class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
||||||
final _key = GlobalKey<AsyncScreenWidgetState>();
|
final _key = GlobalKey<AsyncScreenWidgetState>();
|
||||||
|
|
||||||
UsersList _users;
|
late UsersList _users;
|
||||||
GroupMembersList _members;
|
late GroupMembersList _members;
|
||||||
|
|
||||||
Future<void> _load() async {
|
Future<void> _load() async {
|
||||||
_members = await GroupsHelper.getMembersList(forezGroup.id);
|
_members = await GroupsHelper.getMembersList(forezGroup!.id);
|
||||||
_users = await UsersHelper().getListWithThrow(_members.usersID);
|
_users = await UsersHelper().getListWithThrow(_members.usersID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
|||||||
AsyncScreenWidget(
|
AsyncScreenWidget(
|
||||||
onReload: _load,
|
onReload: _load,
|
||||||
onBuild: onBuild,
|
onBuild: onBuild,
|
||||||
errorMessage: tr("Failed to load members list!"),
|
errorMessage: tr("Failed to load members list!")!,
|
||||||
key: _key,
|
key: _key,
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
@ -88,13 +88,13 @@ class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
|||||||
"Do you really want to cancel the invitation sent to %u%?",
|
"Do you really want to cancel the invitation sent to %u%?",
|
||||||
args: {"u": user.fullName}))) return;
|
args: {"u": user.fullName}))) return;
|
||||||
|
|
||||||
await GroupsHelper.cancelInvitation(forezGroup.id, user.id);
|
await GroupsHelper.cancelInvitation(forezGroup!.id, user.id);
|
||||||
_key.currentState.refresh();
|
_key.currentState!.refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _PopupMenuActions.ACCEPT_REQUEST:
|
case _PopupMenuActions.ACCEPT_REQUEST:
|
||||||
await GroupsHelper.respondRequest(forezGroup.id, user.id, true);
|
await GroupsHelper.respondRequest(forezGroup!.id, user.id, true);
|
||||||
_key.currentState.refresh();
|
_key.currentState!.refresh();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case _PopupMenuActions.REJECT_REQUEST:
|
case _PopupMenuActions.REJECT_REQUEST:
|
||||||
@ -104,13 +104,13 @@ class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
|||||||
"Do you really want to reject the request of %u% to join the Forez group?",
|
"Do you really want to reject the request of %u% to join the Forez group?",
|
||||||
args: {"u": user.fullName}))) return;
|
args: {"u": user.fullName}))) return;
|
||||||
|
|
||||||
await GroupsHelper.respondRequest(forezGroup.id, user.id, false);
|
await GroupsHelper.respondRequest(forezGroup!.id, user.id, false);
|
||||||
_key.currentState.refresh();
|
_key.currentState!.refresh();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
logError(e, s);
|
logError(e, s);
|
||||||
snack(context, tr("Error while processing action!"));
|
snack(context, tr("Error while processing action!")!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,7 +125,7 @@ class _ForezDirectoryScreenState extends State<ForezDirectoryScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _openUserProfile(User user) =>
|
void _openUserProfile(User user) =>
|
||||||
MainController.of(context).openUserPage(user.id);
|
MainController.of(context)!.openUserPage(user.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ForezMemberTile extends StatelessWidget {
|
class _ForezMemberTile extends StatelessWidget {
|
||||||
@ -135,11 +135,11 @@ class _ForezMemberTile extends StatelessWidget {
|
|||||||
final Function(User) onTap;
|
final Function(User) onTap;
|
||||||
|
|
||||||
const _ForezMemberTile({
|
const _ForezMemberTile({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.user,
|
required this.user,
|
||||||
@required this.member,
|
required this.member,
|
||||||
@required this.selectedAction,
|
required this.selectedAction,
|
||||||
@required this.onTap,
|
required this.onTap,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -147,7 +147,7 @@ class _ForezMemberTile extends StatelessWidget {
|
|||||||
leading: AccountImageWidget(user: user),
|
leading: AccountImageWidget(user: user),
|
||||||
title: Text(user.fullName),
|
title: Text(user.fullName),
|
||||||
subtitle: Text(member.membershipText),
|
subtitle: Text(member.membershipText),
|
||||||
trailing: !member.isAtLeastMember && forezGroup.isAtLeastModerator
|
trailing: !member.isAtLeastMember && forezGroup!.isAtLeastModerator
|
||||||
? (member.isInvited
|
? (member.isInvited
|
||||||
? _buildInvitedButton()
|
? _buildInvitedButton()
|
||||||
: _buildRequestedButton())
|
: _buildRequestedButton())
|
||||||
@ -155,7 +155,7 @@ class _ForezMemberTile extends StatelessWidget {
|
|||||||
onTap: member.isAtLeastMember ? () => onTap(user) : null,
|
onTap: member.isAtLeastMember ? () => onTap(user) : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildConversationButton() => user.id == userID()
|
Widget? _buildConversationButton() => user.id == userID()
|
||||||
? null
|
? null
|
||||||
: IconButton(
|
: IconButton(
|
||||||
icon: Icon(Icons.message),
|
icon: Icon(Icons.message),
|
||||||
@ -201,18 +201,13 @@ class _MembershipButton extends StatelessWidget {
|
|||||||
final IconData icon;
|
final IconData icon;
|
||||||
|
|
||||||
const _MembershipButton({
|
const _MembershipButton({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.user,
|
required this.user,
|
||||||
@required this.action,
|
required this.action,
|
||||||
@required this.onTap,
|
required this.onTap,
|
||||||
@required this.color,
|
required this.color,
|
||||||
@required this.icon,
|
required this.icon,
|
||||||
}) : assert(user != null),
|
}) : super(key: key);
|
||||||
assert(action != null),
|
|
||||||
assert(onTap != null),
|
|
||||||
assert(color != null),
|
|
||||||
assert(icon != null),
|
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => ElevatedButton(
|
Widget build(BuildContext context) => ElevatedButton(
|
||||||
|
@ -2,11 +2,17 @@
|
|||||||
// Generated file. Do not edit.
|
// Generated file. Do not edit.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
// ignore_for_file: directives_ordering
|
||||||
// ignore_for_file: lines_longer_than_80_chars
|
// ignore_for_file: lines_longer_than_80_chars
|
||||||
|
// ignore_for_file: depend_on_referenced_packages
|
||||||
|
|
||||||
import 'package:file_picker/src/file_picker_web.dart';
|
import 'package:connectivity_plus_web/connectivity_plus_web.dart';
|
||||||
|
import 'package:file_picker/_internal/file_picker_web.dart';
|
||||||
import 'package:firebase_core_web/firebase_core_web.dart';
|
import 'package:firebase_core_web/firebase_core_web.dart';
|
||||||
import 'package:firebase_messaging_web/firebase_messaging_web.dart';
|
import 'package:firebase_messaging_web/firebase_messaging_web.dart';
|
||||||
|
import 'package:image_cropper_for_web/image_cropper_for_web.dart';
|
||||||
|
import 'package:image_picker_for_web/image_picker_for_web.dart';
|
||||||
|
import 'package:package_info_plus_web/package_info_plus_web.dart';
|
||||||
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
import 'package:shared_preferences_web/shared_preferences_web.dart';
|
||||||
import 'package:url_launcher_web/url_launcher_web.dart';
|
import 'package:url_launcher_web/url_launcher_web.dart';
|
||||||
import 'package:video_player_web/video_player_web.dart';
|
import 'package:video_player_web/video_player_web.dart';
|
||||||
@ -16,9 +22,13 @@ import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
|||||||
|
|
||||||
// ignore: public_member_api_docs
|
// ignore: public_member_api_docs
|
||||||
void registerPlugins(Registrar registrar) {
|
void registerPlugins(Registrar registrar) {
|
||||||
|
ConnectivityPlusPlugin.registerWith(registrar);
|
||||||
FilePickerWeb.registerWith(registrar);
|
FilePickerWeb.registerWith(registrar);
|
||||||
FirebaseCoreWeb.registerWith(registrar);
|
FirebaseCoreWeb.registerWith(registrar);
|
||||||
FirebaseMessagingWeb.registerWith(registrar);
|
FirebaseMessagingWeb.registerWith(registrar);
|
||||||
|
ImageCropperPlugin.registerWith(registrar);
|
||||||
|
ImagePickerPlugin.registerWith(registrar);
|
||||||
|
PackageInfoPlugin.registerWith(registrar);
|
||||||
SharedPreferencesPlugin.registerWith(registrar);
|
SharedPreferencesPlugin.registerWith(registrar);
|
||||||
UrlLauncherPlugin.registerWith(registrar);
|
UrlLauncherPlugin.registerWith(registrar);
|
||||||
VideoPlayerPlugin.registerWith(registrar);
|
VideoPlayerPlugin.registerWith(registrar);
|
||||||
|
@ -26,7 +26,7 @@ enum CreateAccountResult {
|
|||||||
|
|
||||||
class AccountHelper {
|
class AccountHelper {
|
||||||
// Current user ID
|
// Current user ID
|
||||||
static int _currentUserID = -1;
|
static int? _currentUserID = -1;
|
||||||
|
|
||||||
/// Checkout whether current user is signed in or not
|
/// Checkout whether current user is signed in or not
|
||||||
///
|
///
|
||||||
@ -67,7 +67,7 @@ class AccountHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save current user ID
|
// Save current user ID
|
||||||
final preferences = await PreferencesHelper.getInstance();
|
final preferences = await (PreferencesHelper.getInstance());
|
||||||
await preferences.setInt(PreferencesKeyList.USER_ID, userID);
|
await preferences.setInt(PreferencesKeyList.USER_ID, userID);
|
||||||
_currentUserID = userID;
|
_currentUserID = userID;
|
||||||
|
|
||||||
@ -130,14 +130,14 @@ class AccountHelper {
|
|||||||
.getObject()["exists"];
|
.getObject()["exists"];
|
||||||
|
|
||||||
/// Get current user email address
|
/// Get current user email address
|
||||||
static Future<String> getCurrentAccountEmailAddress() async =>
|
static Future<String?> getCurrentAccountEmailAddress() async =>
|
||||||
(await APIRequest.withLogin("account/mail")
|
(await APIRequest.withLogin("account/mail")
|
||||||
.execWithThrowGetObject())["mail"];
|
.execWithThrowGetObject())["mail"];
|
||||||
|
|
||||||
/// Check out whether security questions have been set for an account or not
|
/// Check out whether security questions have been set for an account or not
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<bool> hasSecurityQuestions(String email) async =>
|
static Future<bool?> hasSecurityQuestions(String email) async =>
|
||||||
(await APIRequest.withoutLogin("account/has_security_questions")
|
(await APIRequest.withoutLogin("account/has_security_questions")
|
||||||
.addString("email", email)
|
.addString("email", email)
|
||||||
.execWithThrow())
|
.execWithThrow())
|
||||||
@ -146,7 +146,7 @@ class AccountHelper {
|
|||||||
/// Get the security questions of the user
|
/// Get the security questions of the user
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<List<String>> getSecurityQuestions(String email) async =>
|
static Future<List<String>?> getSecurityQuestions(String? email) async =>
|
||||||
((await APIRequest.withoutLogin("account/get_security_questions")
|
((await APIRequest.withoutLogin("account/get_security_questions")
|
||||||
.addString("email", email)
|
.addString("email", email)
|
||||||
.execWithThrow())
|
.execWithThrow())
|
||||||
@ -158,8 +158,8 @@ class AccountHelper {
|
|||||||
/// Throws an [Exception] in case of failure
|
/// Throws an [Exception] in case of failure
|
||||||
///
|
///
|
||||||
/// Returns a password reset token in case of success
|
/// Returns a password reset token in case of success
|
||||||
static Future<String> checkAnswers(
|
static Future<String?> checkAnswers(
|
||||||
String email, List<String> answers) async =>
|
String? email, List<String> answers) async =>
|
||||||
(await APIRequest.withoutLogin("account/check_security_answers")
|
(await APIRequest.withoutLogin("account/check_security_answers")
|
||||||
.addString("email", email)
|
.addString("email", email)
|
||||||
.addString("answers",
|
.addString("answers",
|
||||||
@ -174,7 +174,7 @@ class AccountHelper {
|
|||||||
String token) async {
|
String token) async {
|
||||||
final response =
|
final response =
|
||||||
await APIRequest.withoutLogin("account/check_password_reset_token")
|
await APIRequest.withoutLogin("account/check_password_reset_token")
|
||||||
.addString("token", token)
|
.addString("reset_token", token)
|
||||||
.execWithThrowGetObject();
|
.execWithThrowGetObject();
|
||||||
|
|
||||||
return ResCheckPasswordToken(
|
return ResCheckPasswordToken(
|
||||||
@ -190,12 +190,12 @@ class AccountHelper {
|
|||||||
static Future<void> changeAccountPassword(
|
static Future<void> changeAccountPassword(
|
||||||
String token, String password) async =>
|
String token, String password) async =>
|
||||||
await APIRequest.withoutLogin("account/reset_user_passwd")
|
await APIRequest.withoutLogin("account/reset_user_passwd")
|
||||||
.addString("token", token)
|
.addString("reset_token", token)
|
||||||
.addString("password", password)
|
.addString("password", password)
|
||||||
.execWithThrow();
|
.execWithThrow();
|
||||||
|
|
||||||
/// Get current user ID from the server
|
/// Get current user ID from the server
|
||||||
Future<int> _downloadCurrentUserID() async {
|
Future<int?> _downloadCurrentUserID() async {
|
||||||
final response = await APIRequest.withLogin("account/id").exec();
|
final response = await APIRequest.withLogin("account/id").exec();
|
||||||
|
|
||||||
if (response.code != 200) return null;
|
if (response.code != 200) return null;
|
||||||
@ -210,10 +210,10 @@ class AccountHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if current user ID is loaded or not
|
/// Check if current user ID is loaded or not
|
||||||
static bool get isUserIDLoaded => _currentUserID > 0;
|
static bool get isUserIDLoaded => _currentUserID! > 0;
|
||||||
|
|
||||||
/// Get the ID of the currently signed in user
|
/// Get the ID of the currently signed in user
|
||||||
static int getCurrentUserID() {
|
static int? getCurrentUserID() {
|
||||||
if (_currentUserID == -1) throw "Current user ID has not been loaded yet!";
|
if (_currentUserID == -1) throw "Current user ID has not been loaded yet!";
|
||||||
return _currentUserID;
|
return _currentUserID;
|
||||||
}
|
}
|
||||||
|
@ -41,13 +41,13 @@ class APIHelper {
|
|||||||
else
|
else
|
||||||
url = Uri.https(config().apiServerName, path);
|
url = Uri.https(config().apiServerName, path);
|
||||||
|
|
||||||
final data = FormData.fromMap(request.args);
|
final data = FormData.fromMap(request.args!);
|
||||||
|
|
||||||
// Process files (if required)
|
// Process files (if required)
|
||||||
if (multipart) {
|
if (multipart) {
|
||||||
// Process filesystem files
|
// Process filesystem files
|
||||||
for (final key in request.files.keys) {
|
for (final key in request.files.keys) {
|
||||||
var v = request.files[key];
|
var v = request.files[key]!;
|
||||||
data.files.add(MapEntry(
|
data.files.add(MapEntry(
|
||||||
key,
|
key,
|
||||||
await MultipartFile.fromFile(v.path,
|
await MultipartFile.fromFile(v.path,
|
||||||
@ -56,11 +56,11 @@ class APIHelper {
|
|||||||
|
|
||||||
// Process in-memory files
|
// Process in-memory files
|
||||||
for (final key in request.bytesFiles.keys) {
|
for (final key in request.bytesFiles.keys) {
|
||||||
var v = request.bytesFiles[key];
|
var v = request.bytesFiles[key]!;
|
||||||
data.files.add(MapEntry(
|
data.files.add(MapEntry(
|
||||||
key,
|
key,
|
||||||
MultipartFile.fromBytes(
|
MultipartFile.fromBytes(
|
||||||
v.bytes,
|
v.bytes!,
|
||||||
filename: v.filename.split("/").last,
|
filename: v.filename.split("/").last,
|
||||||
contentType: v.type,
|
contentType: v.type,
|
||||||
)));
|
)));
|
||||||
@ -85,9 +85,9 @@ class APIHelper {
|
|||||||
EventsHelper.emit(InvalidLoginTokensEvent());
|
EventsHelper.emit(InvalidLoginTokensEvent());
|
||||||
|
|
||||||
if (response.statusCode != HttpStatus.ok)
|
if (response.statusCode != HttpStatus.ok)
|
||||||
return APIResponse(response.statusCode, response.data);
|
return APIResponse(response.statusCode!, response.data);
|
||||||
|
|
||||||
return APIResponse(response.statusCode, response.data);
|
return APIResponse(response.statusCode!, response.data);
|
||||||
} catch (e, stack) {
|
} catch (e, stack) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
print("Could not execute a request!");
|
print("Could not execute a request!");
|
||||||
|
@ -39,12 +39,12 @@ class CallsHelper {
|
|||||||
.cast<CallMember>());
|
.cast<CallMember>());
|
||||||
|
|
||||||
/// Request an offer to access another peer's stream
|
/// Request an offer to access another peer's stream
|
||||||
static Future<void> requestOffer(int callID, int peerID) async =>
|
static Future<void> requestOffer(int callID, int? peerID) async =>
|
||||||
await ws("calls/request_offer", {"callID": callID, "peerID": peerID});
|
await ws("calls/request_offer", {"callID": callID, "peerID": peerID});
|
||||||
|
|
||||||
/// Send a Session Description message to the server
|
/// Send a Session Description message to the server
|
||||||
static Future<void> sendSessionDescription(
|
static Future<void> sendSessionDescription(
|
||||||
int callID, int peerID, RTCSessionDescription sdp) async =>
|
int callID, int? peerID, RTCSessionDescription sdp) async =>
|
||||||
await ws("calls/signal", {
|
await ws("calls/signal", {
|
||||||
"callID": callID,
|
"callID": callID,
|
||||||
"peerID": peerID,
|
"peerID": peerID,
|
||||||
@ -54,7 +54,7 @@ class CallsHelper {
|
|||||||
|
|
||||||
/// Send an IceCandidate
|
/// Send an IceCandidate
|
||||||
static Future<void> sendIceCandidate(
|
static Future<void> sendIceCandidate(
|
||||||
int callID, int peerID, RTCIceCandidate candidate) async =>
|
int callID, int? peerID, RTCIceCandidate candidate) async =>
|
||||||
await ws("calls/signal", {
|
await ws("calls/signal", {
|
||||||
"callID": callID,
|
"callID": callID,
|
||||||
"peerID": peerID,
|
"peerID": peerID,
|
||||||
|
@ -27,7 +27,7 @@ class CommentsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a single comment from the server, specified by its [id]
|
/// Get a single comment from the server, specified by its [id]
|
||||||
Future<Comment> getSingle(int id) async {
|
Future<Comment?> getSingle(int id) async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "comments/get_single",
|
uri: "comments/get_single",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -39,7 +39,7 @@ class CommentsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Update comment content
|
/// Update comment content
|
||||||
Future<bool> updateContent(int id, String newContent) async {
|
Future<bool> updateContent(int id, String? newContent) async {
|
||||||
return (await APIRequest(uri: "comments/edit", needLogin: true, args: {
|
return (await APIRequest(uri: "comments/edit", needLogin: true, args: {
|
||||||
"commentID": id.toString(),
|
"commentID": id.toString(),
|
||||||
"content": newContent,
|
"content": newContent,
|
||||||
|
@ -21,7 +21,6 @@ import 'package:comunic/utils/account_utils.dart';
|
|||||||
import 'package:comunic/utils/color_utils.dart';
|
import 'package:comunic/utils/color_utils.dart';
|
||||||
import 'package:comunic/utils/dart_color.dart';
|
import 'package:comunic/utils/dart_color.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Conversation helper
|
/// Conversation helper
|
||||||
///
|
///
|
||||||
@ -39,7 +38,7 @@ class ConversationsHelper {
|
|||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<int> createConversation(NewConversation settings) async {
|
static Future<int> createConversation(NewConversation settings) async {
|
||||||
final response = await APIRequest.withLogin("conversations/create", args: {
|
final response = await APIRequest.withLogin("conversations/create", args: {
|
||||||
"name": settings.name ?? "",
|
"name": settings.name,
|
||||||
"follow": settings.follow ? "true" : "false",
|
"follow": settings.follow ? "true" : "false",
|
||||||
"users": settings.members.join(","),
|
"users": settings.members.join(","),
|
||||||
"color": colorToHex(settings.color)
|
"color": colorToHex(settings.color)
|
||||||
@ -53,7 +52,7 @@ class ConversationsHelper {
|
|||||||
/// Add a member to a conversation.
|
/// Add a member to a conversation.
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> addMember(int convID, int userID) async =>
|
static Future<void> addMember(int? convID, int? userID) async =>
|
||||||
await APIRequest.withLogin("conversations/addMember")
|
await APIRequest.withLogin("conversations/addMember")
|
||||||
.addInt("convID", convID)
|
.addInt("convID", convID)
|
||||||
.addInt("userID", userID)
|
.addInt("userID", userID)
|
||||||
@ -62,7 +61,7 @@ class ConversationsHelper {
|
|||||||
/// Remove a member from a conversation.
|
/// Remove a member from a conversation.
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> removeMember(int convID, int userID) async =>
|
static Future<void> removeMember(int? convID, int? userID) async =>
|
||||||
await APIRequest.withLogin("conversations/removeMember")
|
await APIRequest.withLogin("conversations/removeMember")
|
||||||
.addInt("convID", convID)
|
.addInt("convID", convID)
|
||||||
.addInt("userID", userID)
|
.addInt("userID", userID)
|
||||||
@ -90,8 +89,8 @@ class ConversationsHelper {
|
|||||||
// Update conversation settings
|
// Update conversation settings
|
||||||
if (settings.isComplete)
|
if (settings.isComplete)
|
||||||
request
|
request
|
||||||
.addString("name", settings.name ?? "")
|
.addString("name", settings.name)
|
||||||
.addBool("canEveryoneAddMembers", settings.canEveryoneAddMembers)
|
.addBool("canEveryoneAddMembers", settings.canEveryoneAddMembers!)
|
||||||
.addString("color", colorToHex(settings.color));
|
.addString("color", colorToHex(settings.color));
|
||||||
|
|
||||||
await request.execWithThrow();
|
await request.execWithThrow();
|
||||||
@ -104,7 +103,7 @@ class ConversationsHelper {
|
|||||||
/// Set a new conversation logo
|
/// Set a new conversation logo
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> changeImage(int convID, BytesFile file) async =>
|
static Future<void> changeImage(int? convID, BytesFile file) async =>
|
||||||
await APIRequest.withLogin("conversations/change_image")
|
await APIRequest.withLogin("conversations/change_image")
|
||||||
.addInt("convID", convID)
|
.addInt("convID", convID)
|
||||||
.addBytesFile("file", file)
|
.addBytesFile("file", file)
|
||||||
@ -113,13 +112,13 @@ class ConversationsHelper {
|
|||||||
/// Remove conversation logo
|
/// Remove conversation logo
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> removeLogo(int convID) async =>
|
static Future<void> removeLogo(int? convID) async =>
|
||||||
await APIRequest.withLogin("conversations/delete_image")
|
await APIRequest.withLogin("conversations/delete_image")
|
||||||
.addInt("convID", convID)
|
.addInt("convID", convID)
|
||||||
.execWithThrow();
|
.execWithThrow();
|
||||||
|
|
||||||
/// Delete a conversation specified by its [id]
|
/// Delete a conversation specified by its [id]
|
||||||
Future<void> deleteConversation(int id) async =>
|
Future<void> deleteConversation(int? id) async =>
|
||||||
await APIRequest.withLogin("conversations/delete")
|
await APIRequest.withLogin("conversations/delete")
|
||||||
.addInt("conversationID", id)
|
.addInt("conversationID", id)
|
||||||
.execWithThrow();
|
.execWithThrow();
|
||||||
@ -132,7 +131,7 @@ class ConversationsHelper {
|
|||||||
await APIRequest.withLogin("conversations/getList").execWithThrow();
|
await APIRequest.withLogin("conversations/getList").execWithThrow();
|
||||||
|
|
||||||
ConversationsList list = ConversationsList();
|
ConversationsList list = ConversationsList();
|
||||||
response.getArray().forEach((f) => list.add(apiToConversation(f)));
|
response.getArray()!.forEach((f) => list.add(apiToConversation(f)));
|
||||||
|
|
||||||
// Update the database
|
// Update the database
|
||||||
await ConversationsSerializationHelper().setList(list);
|
await ConversationsSerializationHelper().setList(list);
|
||||||
@ -148,7 +147,7 @@ class ConversationsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get information about a single conversation specified by its [id]
|
/// Get information about a single conversation specified by its [id]
|
||||||
Future<Conversation> _downloadSingle(int id) async {
|
Future<Conversation> _downloadSingle(int? id) async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "conversations/get_single",
|
uri: "conversations/get_single",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -167,7 +166,7 @@ class ConversationsHelper {
|
|||||||
/// case of failure
|
/// case of failure
|
||||||
///
|
///
|
||||||
/// Return value of this method is never null.
|
/// Return value of this method is never null.
|
||||||
Future<Conversation> getSingle(int id, {bool force = false}) async {
|
Future<Conversation> getSingle(int? id, {bool force = false}) async {
|
||||||
if (force ||
|
if (force ||
|
||||||
!await ConversationsSerializationHelper().any((c) => c.id == id))
|
!await ConversationsSerializationHelper().any((c) => c.id == id))
|
||||||
return await _downloadSingle(id);
|
return await _downloadSingle(id);
|
||||||
@ -178,19 +177,19 @@ class ConversationsHelper {
|
|||||||
/// Get the name of a [conversation]. This requires information
|
/// Get the name of a [conversation]. This requires information
|
||||||
/// about the users of this conversation
|
/// about the users of this conversation
|
||||||
static String getConversationName(
|
static String getConversationName(
|
||||||
Conversation conversation, UsersList users) {
|
Conversation conversation, UsersList? users) {
|
||||||
if (conversation.hasName) return conversation.name;
|
if (conversation.hasName) return conversation.name!;
|
||||||
|
|
||||||
String name = "";
|
String name = "";
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (int i = 0; i < 3 && i < conversation.members.length; i++)
|
for (int i = 0; i < 3 && i < conversation.members!.length; i++)
|
||||||
if (conversation.members[i].userID != userID()) {
|
if (conversation.members![i].userID != userID()) {
|
||||||
name += (count > 0 ? ", " : "") +
|
name += (count > 0 ? ", " : "") +
|
||||||
users.getUser(conversation.members[i].userID).fullName;
|
users!.getUser(conversation.members![i].userID).fullName;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conversation.members.length > 3) name += ", ...";
|
if (conversation.members!.length > 3) name += ", ...";
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -200,7 +199,7 @@ class ConversationsHelper {
|
|||||||
/// true
|
/// true
|
||||||
///
|
///
|
||||||
/// Throws an exception in case of failure
|
/// Throws an exception in case of failure
|
||||||
Future<int> getPrivate(int userID, {bool allowCreate = true}) async {
|
Future<int> getPrivate(int? userID, {bool allowCreate = true}) async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "conversations/getPrivate",
|
uri: "conversations/getPrivate",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -222,7 +221,7 @@ class ConversationsHelper {
|
|||||||
/// Throws an exception in case of failure
|
/// Throws an exception in case of failure
|
||||||
static Future<String> getConversationNameAsync(
|
static Future<String> getConversationNameAsync(
|
||||||
Conversation conversation) async {
|
Conversation conversation) async {
|
||||||
if (conversation.hasName) return conversation.name;
|
if (conversation.hasName) return conversation.name!;
|
||||||
|
|
||||||
//Get information about the members of the conversation
|
//Get information about the members of the conversation
|
||||||
final members = await UsersHelper().getList(conversation.membersID);
|
final members = await UsersHelper().getList(conversation.membersID);
|
||||||
@ -273,7 +272,7 @@ class ConversationsHelper {
|
|||||||
|
|
||||||
// Parse the response of the server
|
// Parse the response of the server
|
||||||
ConversationMessagesList list = ConversationMessagesList();
|
ConversationMessagesList list = ConversationMessagesList();
|
||||||
response.getArray().forEach((f) {
|
response.getArray()!.forEach((f) {
|
||||||
list.add(
|
list.add(
|
||||||
apiToConversationMessage(f),
|
apiToConversationMessage(f),
|
||||||
);
|
);
|
||||||
@ -294,7 +293,7 @@ class ConversationsHelper {
|
|||||||
/// Throws an exception in case of failure
|
/// Throws an exception in case of failure
|
||||||
Future<ConversationMessagesList> _downloadNewMessagesSingle(
|
Future<ConversationMessagesList> _downloadNewMessagesSingle(
|
||||||
int conversationID,
|
int conversationID,
|
||||||
{int lastMessageID = 0}) async {
|
{int? lastMessageID = 0}) async {
|
||||||
// Execute the request on the server
|
// Execute the request on the server
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "conversations/refresh_single",
|
uri: "conversations/refresh_single",
|
||||||
@ -311,8 +310,8 @@ class ConversationsHelper {
|
|||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
Future<ConversationMessagesList> getOlderMessages({
|
Future<ConversationMessagesList> getOlderMessages({
|
||||||
@required int conversationID,
|
required int conversationID,
|
||||||
@required int oldestMessagesID,
|
required int? oldestMessagesID,
|
||||||
int limit = 15,
|
int limit = 15,
|
||||||
}) async {
|
}) async {
|
||||||
// Perform the request online
|
// Perform the request online
|
||||||
@ -334,8 +333,8 @@ class ConversationsHelper {
|
|||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
Future<ConversationMessagesList> getNewMessages(
|
Future<ConversationMessagesList> getNewMessages(
|
||||||
{@required int conversationID,
|
{required int conversationID,
|
||||||
int lastMessageID = 0,
|
int? lastMessageID = 0,
|
||||||
bool online = true}) async {
|
bool online = true}) async {
|
||||||
if (online)
|
if (online)
|
||||||
return await _downloadNewMessagesSingle(conversationID,
|
return await _downloadNewMessagesSingle(conversationID,
|
||||||
@ -348,8 +347,8 @@ class ConversationsHelper {
|
|||||||
/// Send a new message to the server
|
/// Send a new message to the server
|
||||||
Future<SendMessageResult> sendMessage(
|
Future<SendMessageResult> sendMessage(
|
||||||
NewConversationMessage message, {
|
NewConversationMessage message, {
|
||||||
ProgressCallback sendProgress,
|
ProgressCallback? sendProgress,
|
||||||
CancelToken cancelToken,
|
CancelToken? cancelToken,
|
||||||
}) async {
|
}) async {
|
||||||
final request = APIRequest.withLogin("conversations/sendMessage")
|
final request = APIRequest.withLogin("conversations/sendMessage")
|
||||||
.addInt("conversationID", message.conversationID)
|
.addInt("conversationID", message.conversationID)
|
||||||
@ -388,7 +387,7 @@ class ConversationsHelper {
|
|||||||
await ConversationsMessagesSerializationHelper(msg.convID).remove(msg);
|
await ConversationsMessagesSerializationHelper(msg.convID).remove(msg);
|
||||||
|
|
||||||
/// Update a message content
|
/// Update a message content
|
||||||
Future<bool> updateMessage(int id, String newContent) async {
|
Future<bool> updateMessage(int? id, String newContent) async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "conversations/updateMessage",
|
uri: "conversations/updateMessage",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -400,7 +399,7 @@ class ConversationsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Delete permanently a message specified by its [id]
|
/// Delete permanently a message specified by its [id]
|
||||||
Future<bool> deleteMessage(int id) async {
|
Future<bool> deleteMessage(int? id) async {
|
||||||
// Delete the message online
|
// Delete the message online
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "conversations/deleteMessage",
|
uri: "conversations/deleteMessage",
|
||||||
@ -418,7 +417,7 @@ class ConversationsHelper {
|
|||||||
static Future<UnreadConversationsList> getListUnread() async {
|
static Future<UnreadConversationsList> getListUnread() async {
|
||||||
final list = (await APIRequest.withLogin("conversations/get_list_unread")
|
final list = (await APIRequest.withLogin("conversations/get_list_unread")
|
||||||
.execWithThrow())
|
.execWithThrow())
|
||||||
.getArray();
|
.getArray()!;
|
||||||
|
|
||||||
return UnreadConversationsList()
|
return UnreadConversationsList()
|
||||||
..addAll(list.map((f) => UnreadConversation(
|
..addAll(list.map((f) => UnreadConversation(
|
||||||
@ -431,7 +430,7 @@ class ConversationsHelper {
|
|||||||
/// conversation through WebSocket
|
/// conversation through WebSocket
|
||||||
Future<void> registerConversationEvents(int id) async {
|
Future<void> registerConversationEvents(int id) async {
|
||||||
if (_registeredConversations.containsKey(id))
|
if (_registeredConversations.containsKey(id))
|
||||||
_registeredConversations[id]++;
|
_registeredConversations.update(id, (value) => value + 1);
|
||||||
else {
|
else {
|
||||||
_registeredConversations[id] = 1;
|
_registeredConversations[id] = 1;
|
||||||
await ws("\$main/register_conv", {"convID": id});
|
await ws("\$main/register_conv", {"convID": id});
|
||||||
@ -442,16 +441,16 @@ class ConversationsHelper {
|
|||||||
Future<void> unregisterConversationEvents(int id) async {
|
Future<void> unregisterConversationEvents(int id) async {
|
||||||
if (!_registeredConversations.containsKey(id)) return;
|
if (!_registeredConversations.containsKey(id)) return;
|
||||||
|
|
||||||
_registeredConversations[id]--;
|
_registeredConversations.update(id, (value) => value - 1);
|
||||||
|
|
||||||
if (_registeredConversations[id] <= 0) {
|
if (_registeredConversations[id]! <= 0) {
|
||||||
_registeredConversations.remove(id);
|
_registeredConversations.remove(id);
|
||||||
await ws("\$main/unregister_conv", {"convID": id});
|
await ws("\$main/unregister_conv", {"convID": id});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a notification to inform that the user is writing a message
|
/// Send a notification to inform that the user is writing a message
|
||||||
static Future<void> sendWritingEvent(int convID) async =>
|
static Future<void> sendWritingEvent(int? convID) async =>
|
||||||
await ws("conversations/is_writing", {"convID": convID});
|
await ws("conversations/is_writing", {"convID": convID});
|
||||||
|
|
||||||
/// Turn an API response into a ConversationMessage object
|
/// Turn an API response into a ConversationMessage object
|
||||||
|
@ -9,11 +9,11 @@ import 'package:sqflite/sqflite.dart';
|
|||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
abstract class DatabaseHelper {
|
abstract class DatabaseHelper {
|
||||||
static Database _db;
|
static Database? _db;
|
||||||
|
|
||||||
/// Open the database
|
/// Open the database
|
||||||
static Future<void> open() async {
|
static Future<void> open() async {
|
||||||
if (_db != null && _db.isOpen) return;
|
if (_db != null && _db!.isOpen) return;
|
||||||
|
|
||||||
var databasePath = await getDatabasesPath();
|
var databasePath = await getDatabasesPath();
|
||||||
_db = await openDatabase(
|
_db = await openDatabase(
|
||||||
@ -24,7 +24,7 @@ abstract class DatabaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a database instance
|
/// Get a database instance
|
||||||
static Future<Database> get() async {
|
static Future<Database?> get() async {
|
||||||
await open();
|
await open();
|
||||||
return _db;
|
return _db;
|
||||||
}
|
}
|
||||||
|
@ -18,12 +18,12 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
|
|||||||
|
|
||||||
/// Insert an entry in the database
|
/// Insert an entry in the database
|
||||||
Future<void> _insertDB(T el) async {
|
Future<void> _insertDB(T el) async {
|
||||||
await (await DatabaseHelper.get()).insert(tableName(), el.toMap());
|
await (await DatabaseHelper.get())!.insert(tableName(), el.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update an element in the database
|
/// Update an element in the database
|
||||||
Future<void> _updateDB(T el) async {
|
Future<void> _updateDB(T el) async {
|
||||||
await (await DatabaseHelper.get()).update(
|
await (await DatabaseHelper.get())!.update(
|
||||||
tableName(),
|
tableName(),
|
||||||
el.toMap(),
|
el.toMap(),
|
||||||
where: "${BaseTableContract.C_ID} = ?",
|
where: "${BaseTableContract.C_ID} = ?",
|
||||||
@ -34,14 +34,14 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
|
|||||||
/// Get an element from the database with a specified [id]
|
/// Get an element from the database with a specified [id]
|
||||||
///
|
///
|
||||||
/// Returns null if none found
|
/// Returns null if none found
|
||||||
Future<T> get(int id) async {
|
Future<T?> get(int id) async {
|
||||||
List<Map> maps = await (await DatabaseHelper.get()).query(
|
List<Map> maps = await (await DatabaseHelper.get())!.query(
|
||||||
tableName(),
|
tableName(),
|
||||||
where: '${BaseTableContract.C_ID} = ?',
|
where: '${BaseTableContract.C_ID} = ?',
|
||||||
whereArgs: [id],
|
whereArgs: [id],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (maps.length > 0) return initializeFromMap(maps[0]);
|
if (maps.length > 0) return initializeFromMap(maps[0] as Map<String, dynamic>);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -50,7 +50,7 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
|
|||||||
///
|
///
|
||||||
/// Return true if at least one entry was deleted / false else
|
/// Return true if at least one entry was deleted / false else
|
||||||
Future<bool> delete(int id) async {
|
Future<bool> delete(int id) async {
|
||||||
return await (await DatabaseHelper.get()).delete(
|
return await (await DatabaseHelper.get())!.delete(
|
||||||
tableName(),
|
tableName(),
|
||||||
where: '${BaseTableContract.C_ID} = ?',
|
where: '${BaseTableContract.C_ID} = ?',
|
||||||
whereArgs: [id],
|
whereArgs: [id],
|
||||||
@ -59,22 +59,22 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
|
|||||||
|
|
||||||
/// Get all the entries from the table
|
/// Get all the entries from the table
|
||||||
Future<List<T>> getAll() async {
|
Future<List<T>> getAll() async {
|
||||||
List<Map> maps = await (await DatabaseHelper.get()).query(tableName());
|
List<Map> maps = await (await DatabaseHelper.get())!.query(tableName());
|
||||||
return maps.map((f) => initializeFromMap(f)).toList();
|
return maps.map((f) => initializeFromMap(f as Map<String, dynamic>)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get some entries from the table based on some conditions
|
/// Get some entries from the table based on some conditions
|
||||||
Future<List<T>> getMultiple(
|
Future<List<T>> getMultiple(
|
||||||
{bool distinct,
|
{bool? distinct,
|
||||||
List<String> columns,
|
List<String>? columns,
|
||||||
String where,
|
String? where,
|
||||||
List<dynamic> whereArgs,
|
List<dynamic>? whereArgs,
|
||||||
String groupBy,
|
String? groupBy,
|
||||||
String having,
|
String? having,
|
||||||
String orderBy,
|
String? orderBy,
|
||||||
int limit,
|
int? limit,
|
||||||
int offset}) async {
|
int? offset}) async {
|
||||||
List<Map> maps = await (await DatabaseHelper.get()).query(
|
List<Map> maps = await (await DatabaseHelper.get())!.query(
|
||||||
tableName(),
|
tableName(),
|
||||||
distinct: distinct,
|
distinct: distinct,
|
||||||
columns: columns,
|
columns: columns,
|
||||||
@ -86,12 +86,12 @@ abstract class ModelDatabaseHelper<T extends CacheModel> {
|
|||||||
limit: limit,
|
limit: limit,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
);
|
);
|
||||||
return maps.map((f) => initializeFromMap(f)).toList();
|
return maps.map((f) => initializeFromMap(f as Map<String, dynamic>)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Empty the table
|
/// Empty the table
|
||||||
Future<void> clearTable() async {
|
Future<void> clearTable() async {
|
||||||
await (await DatabaseHelper.get()).execute("DELETE FROM ${tableName()}");
|
await (await DatabaseHelper.get())!.execute("DELETE FROM ${tableName()}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check out whether an element specified with its [id] is present
|
/// Check out whether an element specified with its [id] is present
|
||||||
|
@ -17,14 +17,14 @@ class WSClosedEvent {}
|
|||||||
|
|
||||||
/// New number of notifications
|
/// New number of notifications
|
||||||
class NewNumberNotifsEvent {
|
class NewNumberNotifsEvent {
|
||||||
final int newNum;
|
final int? newNum;
|
||||||
|
|
||||||
NewNumberNotifsEvent(this.newNum);
|
NewNumberNotifsEvent(this.newNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// New number of unread conversations
|
/// New number of unread conversations
|
||||||
class NewNumberUnreadConversations {
|
class NewNumberUnreadConversations {
|
||||||
final int newNum;
|
final int? newNum;
|
||||||
|
|
||||||
NewNumberUnreadConversations(this.newNum);
|
NewNumberUnreadConversations(this.newNum);
|
||||||
}
|
}
|
||||||
@ -45,15 +45,15 @@ class UpdatedCommentEvent {
|
|||||||
|
|
||||||
/// Deleted comment
|
/// Deleted comment
|
||||||
class DeletedCommentEvent {
|
class DeletedCommentEvent {
|
||||||
final int commentID;
|
final int? commentID;
|
||||||
|
|
||||||
DeletedCommentEvent(this.commentID);
|
DeletedCommentEvent(this.commentID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writing message in conversation event
|
/// Writing message in conversation event
|
||||||
class WritingMessageInConversationEvent {
|
class WritingMessageInConversationEvent {
|
||||||
final int convID;
|
final int? convID;
|
||||||
final int userID;
|
final int? userID;
|
||||||
|
|
||||||
WritingMessageInConversationEvent(this.convID, this.userID);
|
WritingMessageInConversationEvent(this.convID, this.userID);
|
||||||
}
|
}
|
||||||
@ -81,31 +81,31 @@ class DeletedConversationMessageEvent {
|
|||||||
|
|
||||||
/// Remove user from conversation
|
/// Remove user from conversation
|
||||||
class RemovedUserFromConversationEvent {
|
class RemovedUserFromConversationEvent {
|
||||||
final int convID;
|
final int? convID;
|
||||||
final int userID;
|
final int? userID;
|
||||||
|
|
||||||
RemovedUserFromConversationEvent(this.convID, this.userID);
|
RemovedUserFromConversationEvent(this.convID, this.userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deleted conversation
|
/// Deleted conversation
|
||||||
class DeletedConversationEvent {
|
class DeletedConversationEvent {
|
||||||
final int convID;
|
final int? convID;
|
||||||
|
|
||||||
DeletedConversationEvent(this.convID);
|
DeletedConversationEvent(this.convID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// User joined call event
|
/// User joined call event
|
||||||
class UserJoinedCallEvent {
|
class UserJoinedCallEvent {
|
||||||
final int callID;
|
final int? callID;
|
||||||
final int userID;
|
final int? userID;
|
||||||
|
|
||||||
UserJoinedCallEvent(this.callID, this.userID);
|
UserJoinedCallEvent(this.callID, this.userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// User left call event
|
/// User left call event
|
||||||
class UserLeftCallEvent {
|
class UserLeftCallEvent {
|
||||||
final int callID;
|
final int? callID;
|
||||||
final int userID;
|
final int? userID;
|
||||||
|
|
||||||
UserLeftCallEvent(this.callID, this.userID);
|
UserLeftCallEvent(this.callID, this.userID);
|
||||||
}
|
}
|
||||||
@ -114,38 +114,36 @@ class UserLeftCallEvent {
|
|||||||
class NewCallSignalEvent {
|
class NewCallSignalEvent {
|
||||||
final int callID;
|
final int callID;
|
||||||
final int peerID;
|
final int peerID;
|
||||||
final RTCSessionDescription sessionDescription;
|
final RTCSessionDescription? sessionDescription;
|
||||||
final RTCIceCandidate candidate;
|
final RTCIceCandidate? candidate;
|
||||||
|
|
||||||
const NewCallSignalEvent({
|
const NewCallSignalEvent({
|
||||||
this.callID,
|
required this.callID,
|
||||||
this.peerID,
|
required this.peerID,
|
||||||
this.sessionDescription,
|
this.sessionDescription,
|
||||||
this.candidate,
|
this.candidate,
|
||||||
}) : assert(callID != null),
|
}) : assert(sessionDescription != null || candidate != null);
|
||||||
assert(peerID != null),
|
|
||||||
assert(sessionDescription != null || candidate != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call peer ready event
|
/// Call peer ready event
|
||||||
class CallPeerReadyEvent {
|
class CallPeerReadyEvent {
|
||||||
final int callID;
|
final int? callID;
|
||||||
final int peerID;
|
final int? peerID;
|
||||||
|
|
||||||
CallPeerReadyEvent(this.callID, this.peerID);
|
CallPeerReadyEvent(this.callID, this.peerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call peer interrupted streaming event
|
/// Call peer interrupted streaming event
|
||||||
class CallPeerInterruptedStreamingEvent {
|
class CallPeerInterruptedStreamingEvent {
|
||||||
final int callID;
|
final int? callID;
|
||||||
final int peerID;
|
final int? peerID;
|
||||||
|
|
||||||
CallPeerInterruptedStreamingEvent(this.callID, this.peerID);
|
CallPeerInterruptedStreamingEvent(this.callID, this.peerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call closed event
|
/// Call closed event
|
||||||
class CallClosedEvent {
|
class CallClosedEvent {
|
||||||
final int callID;
|
final int? callID;
|
||||||
|
|
||||||
CallClosedEvent(this.callID);
|
CallClosedEvent(this.callID);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ class FirebaseMessagingHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a Firebase access token
|
/// Get a Firebase access token
|
||||||
static Future<String> getToken() async {
|
static Future<String?> getToken() async {
|
||||||
return await FirebaseMessaging.instance.getToken();
|
return await FirebaseMessaging.instance.getToken();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import 'package:comunic/models/group.dart';
|
|||||||
class ForezGroupsHelper {
|
class ForezGroupsHelper {
|
||||||
static Future<List<Group>> getForezGroups() async {
|
static Future<List<Group>> getForezGroups() async {
|
||||||
return (await APIRequest.withLogin("forez/get_groups").execWithThrow())
|
return (await APIRequest.withLogin("forez/get_groups").execWithThrow())
|
||||||
.getArray()
|
.getArray()!
|
||||||
.cast<Map<String, dynamic>>()
|
.cast<Map<String, dynamic>>()
|
||||||
.map(GroupsHelper.getGroupFromAPI)
|
.map(GroupsHelper.getGroupFromAPI)
|
||||||
.toList();
|
.toList();
|
||||||
@ -21,10 +21,10 @@ class ForezGroupsHelper {
|
|||||||
///
|
///
|
||||||
/// This methods throws an exception in case of failure
|
/// This methods throws an exception in case of failure
|
||||||
static Future<AdvancedUserInfo> getMemberInfo(int groupID, int userID) async {
|
static Future<AdvancedUserInfo> getMemberInfo(int groupID, int userID) async {
|
||||||
final response = await APIRequest.withLogin("forez/get_member_info")
|
final response = await (APIRequest.withLogin("forez/get_member_info")
|
||||||
.addInt("group", groupID)
|
.addInt("group", groupID)
|
||||||
.addInt("user", userID)
|
.addInt("user", userID)
|
||||||
.execWithThrowGetObject();
|
.execWithThrowGetObject());
|
||||||
|
|
||||||
return UsersHelper.apiToAdvancedUserInfo(response);
|
return UsersHelper.apiToAdvancedUserInfo(response);
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@ import 'package:comunic/models/forez_presence.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
int _cachedGroup;
|
int? _cachedGroup;
|
||||||
PresenceSet _cache;
|
PresenceSet? _cache;
|
||||||
|
|
||||||
class ForezPresenceHelper {
|
class ForezPresenceHelper {
|
||||||
/// Refresh presence cache
|
/// Refresh presence cache
|
||||||
@ -40,16 +40,16 @@ class ForezPresenceHelper {
|
|||||||
/// Get the presences of a given user
|
/// Get the presences of a given user
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<PresenceSet> getForUser(int groupID, int userID) async {
|
static Future<PresenceSet> getForUser(int groupID, int? userID) async {
|
||||||
await _checkCache(groupID);
|
await _checkCache(groupID);
|
||||||
|
|
||||||
return _cache.getForUser(userID);
|
return _cache!.getForUser(userID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get all the available presences
|
/// Get all the available presences
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<PresenceSet> getAll(int groupID) async {
|
static Future<PresenceSet?> getAll(int groupID) async {
|
||||||
await _checkCache(groupID);
|
await _checkCache(groupID);
|
||||||
return _cache;
|
return _cache;
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ import 'package:comunic/lists/friends_list.dart';
|
|||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/models/friend.dart';
|
import 'package:comunic/models/friend.dart';
|
||||||
import 'package:comunic/models/friend_status.dart';
|
import 'package:comunic/models/friend_status.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Friends helper
|
/// Friends helper
|
||||||
///
|
///
|
||||||
@ -16,7 +15,7 @@ class FriendsHelper {
|
|||||||
///
|
///
|
||||||
/// Returns the list of friends in case of success, or null if an error
|
/// Returns the list of friends in case of success, or null if an error
|
||||||
/// occurred
|
/// occurred
|
||||||
Future<FriendsList> _downloadList() async {
|
Future<FriendsList?> _downloadList() async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "friends/getList",
|
uri: "friends/getList",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -30,7 +29,7 @@ class FriendsHelper {
|
|||||||
// Parse and return the list of friends
|
// Parse and return the list of friends
|
||||||
FriendsList list = FriendsList()
|
FriendsList list = FriendsList()
|
||||||
..addAll(response
|
..addAll(response
|
||||||
.getArray()
|
.getArray()!
|
||||||
.cast<Map<String, dynamic>>()
|
.cast<Map<String, dynamic>>()
|
||||||
.map(apiToFriend)
|
.map(apiToFriend)
|
||||||
.toList());
|
.toList());
|
||||||
@ -54,7 +53,7 @@ class FriendsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list, either from an online or an offline source
|
/// Get the list, either from an online or an offline source
|
||||||
Future<FriendsList> getList({@required bool online}) async {
|
Future<FriendsList?> getList({required bool online}) async {
|
||||||
if (online)
|
if (online)
|
||||||
return await _downloadList();
|
return await _downloadList();
|
||||||
else
|
else
|
||||||
@ -132,7 +131,7 @@ class FriendsHelper {
|
|||||||
if (response.code != 200)
|
if (response.code != 200)
|
||||||
throw new Exception("Could not get the list of friends of this user!");
|
throw new Exception("Could not get the list of friends of this user!");
|
||||||
|
|
||||||
return Set<int>.from(response.getArray());
|
return Set<int>.from(response.getArray()!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a friendship request to a specified user
|
/// Send a friendship request to a specified user
|
||||||
|
@ -49,15 +49,15 @@ enum GetAdvancedInfoStatus { SUCCESS, ACCESS_DENIED }
|
|||||||
|
|
||||||
class GetAdvancedInfoResult {
|
class GetAdvancedInfoResult {
|
||||||
final GetAdvancedInfoStatus status;
|
final GetAdvancedInfoStatus status;
|
||||||
final AdvancedGroupInfo info;
|
final AdvancedGroupInfo? info;
|
||||||
|
|
||||||
GetAdvancedInfoResult(this.status, this.info) : assert(status != null);
|
GetAdvancedInfoResult(this.status, this.info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Groups helper
|
/// Groups helper
|
||||||
class GroupsHelper {
|
class GroupsHelper {
|
||||||
/// Download a list of groups information from the server
|
/// Download a list of groups information from the server
|
||||||
Future<GroupsList> _downloadList(Set<int> groups) async {
|
Future<GroupsList?> _downloadList(Set<int?> groups) async {
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "groups/get_multiple_info",
|
uri: "groups/get_multiple_info",
|
||||||
needLogin: true,
|
needLogin: true,
|
||||||
@ -77,7 +77,7 @@ class GroupsHelper {
|
|||||||
|
|
||||||
/// Get a list of groups from the server. In case of error, this method throws
|
/// Get a list of groups from the server. In case of error, this method throws
|
||||||
/// an exception
|
/// an exception
|
||||||
Future<GroupsList> getListOrThrow(Set<int> groups,
|
Future<GroupsList> getListOrThrow(Set<int?> groups,
|
||||||
{bool force = false}) async {
|
{bool force = false}) async {
|
||||||
final list = await getList(groups, force: force);
|
final list = await getList(groups, force: force);
|
||||||
|
|
||||||
@ -87,11 +87,11 @@ class GroupsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get a list of groups from the server
|
/// Get a list of groups from the server
|
||||||
Future<GroupsList> getList(Set<int> groups, {bool force = false}) async {
|
Future<GroupsList?> getList(Set<int?> groups, {bool force = false}) async {
|
||||||
final list = GroupsList();
|
final list = GroupsList();
|
||||||
|
|
||||||
// Check which groups information to download
|
// Check which groups information to download
|
||||||
final toDownload = Set<int>();
|
final toDownload = Set<int?>();
|
||||||
groups.forEach((groupID) {
|
groups.forEach((groupID) {
|
||||||
if (!force && _groupsListCache.containsKey(groupID))
|
if (!force && _groupsListCache.containsKey(groupID))
|
||||||
list[groupID] = _groupsListCache[groupID];
|
list[groupID] = _groupsListCache[groupID];
|
||||||
@ -122,10 +122,10 @@ class GroupsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of groups of a user
|
/// Get the list of groups of a user
|
||||||
Future<Set<int>> getListUser() async =>
|
Future<Set<int?>> getListUser() async =>
|
||||||
(await APIRequest(uri: "groups/get_my_list", needLogin: true).exec())
|
(await APIRequest(uri: "groups/get_my_list", needLogin: true).exec())
|
||||||
.assertOk()
|
.assertOk()
|
||||||
.getArray()
|
.getArray()!
|
||||||
.map((f) => cast<int>(f))
|
.map((f) => cast<int>(f))
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
@ -142,7 +142,7 @@ class GroupsHelper {
|
|||||||
|
|
||||||
/// Perform a simple membership request
|
/// Perform a simple membership request
|
||||||
static Future<bool> _simpleMembershipRequest(int groupID, String uri,
|
static Future<bool> _simpleMembershipRequest(int groupID, String uri,
|
||||||
{Map<String, String> args}) async =>
|
{Map<String, String>? args}) async =>
|
||||||
(await (APIRequest.withLogin(uri)
|
(await (APIRequest.withLogin(uri)
|
||||||
..addInt("id", groupID)
|
..addInt("id", groupID)
|
||||||
..addArgs(args == null ? Map() : args))
|
..addArgs(args == null ? Map() : args))
|
||||||
@ -176,7 +176,7 @@ class GroupsHelper {
|
|||||||
.isOK;
|
.isOK;
|
||||||
|
|
||||||
/// Get advanced information about the user
|
/// Get advanced information about the user
|
||||||
Future<GetAdvancedInfoResult> getAdvancedInfo(int groupID) async {
|
Future<GetAdvancedInfoResult> getAdvancedInfo(int? groupID) async {
|
||||||
// Get advanced information about the user
|
// Get advanced information about the user
|
||||||
final result =
|
final result =
|
||||||
await (APIRequest(uri: "groups/get_advanced_info", needLogin: true)
|
await (APIRequest(uri: "groups/get_advanced_info", needLogin: true)
|
||||||
@ -202,7 +202,7 @@ class GroupsHelper {
|
|||||||
/// change in the future
|
/// change in the future
|
||||||
///
|
///
|
||||||
/// Throws in case of error
|
/// Throws in case of error
|
||||||
Future<AdvancedGroupInfo> getSettings(int groupID) async {
|
Future<AdvancedGroupInfo?> getSettings(int groupID) async {
|
||||||
final groupInfo = await getAdvancedInfo(groupID);
|
final groupInfo = await getAdvancedInfo(groupID);
|
||||||
|
|
||||||
if (groupInfo.status != GetAdvancedInfoStatus.SUCCESS)
|
if (groupInfo.status != GetAdvancedInfoStatus.SUCCESS)
|
||||||
@ -239,7 +239,7 @@ class GroupsHelper {
|
|||||||
"posts_level",
|
"posts_level",
|
||||||
invertMap(
|
invertMap(
|
||||||
_APIGroupsPostsCreationLevelsMap)[settings.postCreationLevel])
|
_APIGroupsPostsCreationLevelsMap)[settings.postCreationLevel])
|
||||||
.addBool("is_members_list_public", settings.isMembersListPublic)
|
.addBool("is_members_list_public", settings.isMembersListPublic!)
|
||||||
.addString("description", settings.description)
|
.addString("description", settings.description)
|
||||||
.addString("url", settings.url)
|
.addString("url", settings.url)
|
||||||
.execWithThrow();
|
.execWithThrow();
|
||||||
@ -248,7 +248,7 @@ class GroupsHelper {
|
|||||||
/// Upload a new logo
|
/// Upload a new logo
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> uploadNewLogo(int groupID, Uint8List bytes) async =>
|
static Future<void> uploadNewLogo(int groupID, Uint8List? bytes) async =>
|
||||||
await APIRequest(uri: "groups/upload_logo", needLogin: true)
|
await APIRequest(uri: "groups/upload_logo", needLogin: true)
|
||||||
.addInt("id", groupID)
|
.addInt("id", groupID)
|
||||||
.addBytesFile("logo", BytesFile("logo.png", bytes))
|
.addBytesFile("logo", BytesFile("logo.png", bytes))
|
||||||
@ -279,7 +279,7 @@ class GroupsHelper {
|
|||||||
..addAll((await APIRequest(uri: "groups/get_members", needLogin: true)
|
..addAll((await APIRequest(uri: "groups/get_members", needLogin: true)
|
||||||
.addInt("id", groupID)
|
.addInt("id", groupID)
|
||||||
.execWithThrow())
|
.execWithThrow())
|
||||||
.getArray()
|
.getArray()!
|
||||||
.map((f) => _apiToGroupMembership(f))
|
.map((f) => _apiToGroupMembership(f))
|
||||||
.toList());
|
.toList());
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ class GroupsHelper {
|
|||||||
/// Cancel a group membership invitation
|
/// Cancel a group membership invitation
|
||||||
///
|
///
|
||||||
/// Throws an exception in case of failure
|
/// Throws an exception in case of failure
|
||||||
static Future<void> cancelInvitation(int groupID, int userID) async =>
|
static Future<void> cancelInvitation(int groupID, int? userID) async =>
|
||||||
await APIRequest.withLogin("groups/cancel_invitation")
|
await APIRequest.withLogin("groups/cancel_invitation")
|
||||||
.addInt("groupID", groupID)
|
.addInt("groupID", groupID)
|
||||||
.addInt("userID", userID)
|
.addInt("userID", userID)
|
||||||
@ -305,7 +305,7 @@ class GroupsHelper {
|
|||||||
///
|
///
|
||||||
/// Throws an exception in case of failure
|
/// Throws an exception in case of failure
|
||||||
static Future<void> respondRequest(
|
static Future<void> respondRequest(
|
||||||
int groupID, int userID, bool accept) async =>
|
int groupID, int? userID, bool accept) async =>
|
||||||
await APIRequest.withLogin("groups/respond_request")
|
await APIRequest.withLogin("groups/respond_request")
|
||||||
.addInt("groupID", groupID)
|
.addInt("groupID", groupID)
|
||||||
.addInt("userID", userID)
|
.addInt("userID", userID)
|
||||||
@ -351,7 +351,7 @@ class GroupsHelper {
|
|||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> setConversationVisibility(
|
static Future<void> setConversationVisibility(
|
||||||
int convID, GroupMembershipLevel newLevel) async =>
|
int? convID, GroupMembershipLevel? newLevel) async =>
|
||||||
await APIRequest.withLogin("groups/set_conversation_visibility")
|
await APIRequest.withLogin("groups/set_conversation_visibility")
|
||||||
.addInt("conv_id", convID)
|
.addInt("conv_id", convID)
|
||||||
.addString(
|
.addString(
|
||||||
@ -364,7 +364,7 @@ class GroupsHelper {
|
|||||||
/// Delete a group's conversation
|
/// Delete a group's conversation
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> deleteConversation(int convID) async =>
|
static Future<void> deleteConversation(int? convID) async =>
|
||||||
await APIRequest.withLogin("groups/delete_conversation")
|
await APIRequest.withLogin("groups/delete_conversation")
|
||||||
.addInt("conv_id", convID)
|
.addInt("conv_id", convID)
|
||||||
.execWithThrow();
|
.execWithThrow();
|
||||||
@ -376,11 +376,11 @@ class GroupsHelper {
|
|||||||
name: map["name"],
|
name: map["name"],
|
||||||
iconURL: map["icon_url"],
|
iconURL: map["icon_url"],
|
||||||
numberMembers: map["number_members"],
|
numberMembers: map["number_members"],
|
||||||
membershipLevel: APIGroupsMembershipLevelsMap[map["membership"]],
|
membershipLevel: APIGroupsMembershipLevelsMap[map["membership"]]!,
|
||||||
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]],
|
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]]!,
|
||||||
registrationLevel:
|
registrationLevel:
|
||||||
_APIGroupsRegistrationLevelsMap[map["registration_level"]],
|
_APIGroupsRegistrationLevelsMap[map["registration_level"]]!,
|
||||||
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]],
|
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]]!,
|
||||||
virtualDirectory: nullToEmpty(map["virtual_directory"]),
|
virtualDirectory: nullToEmpty(map["virtual_directory"]),
|
||||||
following: map["following"]);
|
following: map["following"]);
|
||||||
}
|
}
|
||||||
@ -392,11 +392,11 @@ class GroupsHelper {
|
|||||||
name: map["name"],
|
name: map["name"],
|
||||||
iconURL: map["icon_url"],
|
iconURL: map["icon_url"],
|
||||||
numberMembers: map["number_members"],
|
numberMembers: map["number_members"],
|
||||||
membershipLevel: APIGroupsMembershipLevelsMap[map["membership"]],
|
membershipLevel: APIGroupsMembershipLevelsMap[map["membership"]]!,
|
||||||
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]],
|
visibilityLevel: _APIGroupsVisibilityLevelsMap[map["visibility"]]!,
|
||||||
registrationLevel:
|
registrationLevel:
|
||||||
_APIGroupsRegistrationLevelsMap[map["registration_level"]],
|
_APIGroupsRegistrationLevelsMap[map["registration_level"]]!,
|
||||||
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]],
|
postCreationLevel: _APIGroupsPostsCreationLevelsMap[map["posts_level"]]!,
|
||||||
isMembersListPublic: map["is_members_list_public"],
|
isMembersListPublic: map["is_members_list_public"],
|
||||||
virtualDirectory: nullToEmpty(map["virtual_directory"]),
|
virtualDirectory: nullToEmpty(map["virtual_directory"]),
|
||||||
following: map["following"],
|
following: map["following"],
|
||||||
@ -418,6 +418,6 @@ class GroupsHelper {
|
|||||||
userID: row["user_id"],
|
userID: row["user_id"],
|
||||||
groupID: row["group_id"],
|
groupID: row["group_id"],
|
||||||
timeCreate: row["time_create"],
|
timeCreate: row["time_create"],
|
||||||
level: APIGroupsMembershipLevelsMap[row["level"]],
|
level: APIGroupsMembershipLevelsMap[row["level"]]!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ class IndependentPushNotificationsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Configure independent push notification services with a pull URL
|
/// Configure independent push notification services with a pull URL
|
||||||
static Future<void> configure(String wsURL) async {
|
static Future<void> configure(String? wsURL) async {
|
||||||
await platform.invokeMethod("configure", wsURL);
|
await platform.invokeMethod("configure", wsURL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import 'package:comunic/enums/likes_type.dart';
|
import 'package:comunic/enums/likes_type.dart';
|
||||||
import 'package:comunic/helpers/websocket_helper.dart';
|
import 'package:comunic/helpers/websocket_helper.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Likes helper
|
/// Likes helper
|
||||||
///
|
///
|
||||||
@ -16,9 +15,9 @@ const LikesAPIMap = {
|
|||||||
class LikesHelper {
|
class LikesHelper {
|
||||||
/// Update liking status of an element
|
/// Update liking status of an element
|
||||||
Future<void> setLiking({
|
Future<void> setLiking({
|
||||||
@required LikesType type,
|
required LikesType type,
|
||||||
@required bool like,
|
required bool like,
|
||||||
@required int id,
|
required int id,
|
||||||
}) async {
|
}) async {
|
||||||
return (await ws("likes/update", {
|
return (await ws("likes/update", {
|
||||||
"type": LikesAPIMap[type],
|
"type": LikesAPIMap[type],
|
||||||
|
@ -75,15 +75,15 @@ class NotificationsHelper {
|
|||||||
// Parse the list of notifications
|
// Parse the list of notifications
|
||||||
return NotificationsList()
|
return NotificationsList()
|
||||||
..addAll(response
|
..addAll(response
|
||||||
.getArray()
|
.getArray()!
|
||||||
.map((f) => Notification(
|
.map((f) => Notification(
|
||||||
id: f["id"],
|
id: f["id"],
|
||||||
timeCreate: f["time_create"],
|
timeCreate: f["time_create"],
|
||||||
seen: f["seen"],
|
seen: f["seen"],
|
||||||
fromUser: f["from_user_id"],
|
fromUser: f["from_user_id"],
|
||||||
onElemId: f["on_elem_id"],
|
onElemId: f["on_elem_id"],
|
||||||
onElemType: _NotificationElementTypeAPImapping[f["on_elem_type"]],
|
onElemType: _NotificationElementTypeAPImapping[f["on_elem_type"]]!,
|
||||||
type: _NotificationsTypeAPImapping[f["type"]],
|
type: _NotificationsTypeAPImapping[f["type"]]!,
|
||||||
fromContainerId: f["from_container_id"],
|
fromContainerId: f["from_container_id"],
|
||||||
fromContainerType: f["from_container_type"] == ""
|
fromContainerType: f["from_container_type"] == ""
|
||||||
? null
|
? null
|
||||||
|
@ -55,7 +55,7 @@ class PostsHelper {
|
|||||||
|
|
||||||
/// Get the list of latest posts. Return the list of posts or null in case of
|
/// Get the list of latest posts. Return the list of posts or null in case of
|
||||||
/// failure
|
/// failure
|
||||||
Future<PostsList> getLatest({int from = 0}) async {
|
Future<PostsList?> getLatest({int from = 0}) async {
|
||||||
final response =
|
final response =
|
||||||
await APIRequest(uri: "posts/get_latest", needLogin: true, args: {
|
await APIRequest(uri: "posts/get_latest", needLogin: true, args: {
|
||||||
"include_groups": true.toString(),
|
"include_groups": true.toString(),
|
||||||
@ -66,7 +66,8 @@ class PostsHelper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Parse & return the list of posts
|
// Parse & return the list of posts
|
||||||
return PostsList()..addAll(response.getArray().map((f) => _apiToPost(f)));
|
return PostsList()
|
||||||
|
..addAll(response.getArray()!.map((f) => _apiToPost(f)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
return null;
|
return null;
|
||||||
@ -74,7 +75,7 @@ class PostsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of posts of a user
|
/// Get the list of posts of a user
|
||||||
Future<PostsList> getUserPosts(int userID, {int from = 0}) async {
|
Future<PostsList?> getUserPosts(int? userID, {int from = 0}) async {
|
||||||
final response = await (APIRequest(uri: "posts/get_user", needLogin: true)
|
final response = await (APIRequest(uri: "posts/get_user", needLogin: true)
|
||||||
..addInt("userID", userID)
|
..addInt("userID", userID)
|
||||||
..addInt("startFrom", from == 0 ? 0 : from - 1))
|
..addInt("startFrom", from == 0 ? 0 : from - 1))
|
||||||
@ -84,7 +85,8 @@ class PostsHelper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Parse & return the list of posts
|
// Parse & return the list of posts
|
||||||
return PostsList()..addAll(response.getArray().map((f) => _apiToPost(f)));
|
return PostsList()
|
||||||
|
..addAll(response.getArray()!.map((f) => _apiToPost(f)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
return null;
|
return null;
|
||||||
@ -92,7 +94,7 @@ class PostsHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of posts of a group
|
/// Get the list of posts of a group
|
||||||
Future<PostsList> getGroupPosts(int groupID, {int from = 0}) async {
|
Future<PostsList?> getGroupPosts(int groupID, {int from = 0}) async {
|
||||||
final response = await (APIRequest(uri: "posts/get_group", needLogin: true)
|
final response = await (APIRequest(uri: "posts/get_group", needLogin: true)
|
||||||
..addInt("groupID", groupID)
|
..addInt("groupID", groupID)
|
||||||
..addInt("startFrom", from == 0 ? 0 : from - 1))
|
..addInt("startFrom", from == 0 ? 0 : from - 1))
|
||||||
@ -102,7 +104,8 @@ class PostsHelper {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// Parse & return the list of posts
|
// Parse & return the list of posts
|
||||||
return PostsList()..addAll(response.getArray().map((f) => _apiToPost(f)));
|
return PostsList()
|
||||||
|
..addAll(response.getArray()!.map((f) => _apiToPost(f)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e.toString());
|
print(e.toString());
|
||||||
return null;
|
return null;
|
||||||
@ -158,13 +161,14 @@ class PostsHelper {
|
|||||||
|
|
||||||
case PostKind.COUNTDOWN:
|
case PostKind.COUNTDOWN:
|
||||||
request.addInt(
|
request.addInt(
|
||||||
"time-end", (post.timeEnd.millisecondsSinceEpoch / 1000).floor());
|
"time-end", (post.timeEnd!.millisecondsSinceEpoch / 1000).floor());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PostKind.SURVEY:
|
case PostKind.SURVEY:
|
||||||
request.addString("question", post.survey.question);
|
request.addString("question", post.survey!.question);
|
||||||
request.addString("answers", post.survey.answers.join("<>"));
|
request.addString("answers", post.survey!.answers.join("<>"));
|
||||||
request.addBool("allowNewAnswers", post.survey.allowNewChoicesCreation);
|
request.addBool(
|
||||||
|
"allowNewAnswers", post.survey!.allowNewChoicesCreation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PostKind.YOUTUBE:
|
case PostKind.YOUTUBE:
|
||||||
@ -173,7 +177,6 @@ class PostsHelper {
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
throw Exception("Unsupported post type :" + post.kind.toString());
|
throw Exception("Unsupported post type :" + post.kind.toString());
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final response = await request.execWithFiles();
|
final response = await request.execWithFiles();
|
||||||
@ -221,7 +224,7 @@ class PostsHelper {
|
|||||||
/// Register to a post events
|
/// Register to a post events
|
||||||
Future<void> registerPostEvents(int id) async {
|
Future<void> registerPostEvents(int id) async {
|
||||||
if (_registeredPosts.containsKey(id))
|
if (_registeredPosts.containsKey(id))
|
||||||
_registeredPosts[id]++;
|
_registeredPosts.update(id, (v) => v + 1);
|
||||||
else {
|
else {
|
||||||
_registeredPosts[id] = 1;
|
_registeredPosts[id] = 1;
|
||||||
await ws("\$main/register_post", {"postID": id});
|
await ws("\$main/register_post", {"postID": id});
|
||||||
@ -232,9 +235,9 @@ class PostsHelper {
|
|||||||
Future<void> unregisterPostEvents(int id) async {
|
Future<void> unregisterPostEvents(int id) async {
|
||||||
if (!_registeredPosts.containsKey(id)) return;
|
if (!_registeredPosts.containsKey(id)) return;
|
||||||
|
|
||||||
_registeredPosts[id]--;
|
_registeredPosts.update(id, (v) => v - 1);
|
||||||
|
|
||||||
if (_registeredPosts[id] <= 0) {
|
if (_registeredPosts[id]! <= 0) {
|
||||||
_registeredPosts.remove(id);
|
_registeredPosts.remove(id);
|
||||||
await ws("\$main/unregister_post", {"postID": id});
|
await ws("\$main/unregister_post", {"postID": id});
|
||||||
}
|
}
|
||||||
@ -242,14 +245,14 @@ class PostsHelper {
|
|||||||
|
|
||||||
/// Turn an API entry into a [Post] object
|
/// Turn an API entry into a [Post] object
|
||||||
Post _apiToPost(Map<String, dynamic> map) {
|
Post _apiToPost(Map<String, dynamic> map) {
|
||||||
final postKind = _APIPostsKindsMap[map["kind"]];
|
final postKind = _APIPostsKindsMap[map["kind"]]!;
|
||||||
|
|
||||||
// Parse comments
|
// Parse comments
|
||||||
CommentsList comments;
|
CommentsList? comments;
|
||||||
if (map["comments"] != null) {
|
if (map["comments"] != null) {
|
||||||
comments = CommentsList();
|
comments = CommentsList();
|
||||||
map["comments"]
|
map["comments"]
|
||||||
.forEach((v) => comments.add(CommentsHelper.apiToComment(v)));
|
.forEach((v) => comments!.add(CommentsHelper.apiToComment(v)));
|
||||||
}
|
}
|
||||||
|
|
||||||
final survey = postKind == PostKind.SURVEY
|
final survey = postKind == PostKind.SURVEY
|
||||||
@ -263,7 +266,7 @@ class PostsHelper {
|
|||||||
groupID: map["group_id"],
|
groupID: map["group_id"],
|
||||||
timeSent: map["post_time"],
|
timeSent: map["post_time"],
|
||||||
content: DisplayedString(map["content"]),
|
content: DisplayedString(map["content"]),
|
||||||
visibilityLevel: _APIPostsVisibilityLevelMap[map["visibility_level"]],
|
visibilityLevel: _APIPostsVisibilityLevelMap[map["visibility_level"]]!,
|
||||||
kind: postKind,
|
kind: postKind,
|
||||||
fileSize: map["file_size"],
|
fileSize: map["file_size"],
|
||||||
fileType: map["file_type"],
|
fileType: map["file_type"],
|
||||||
@ -276,7 +279,7 @@ class PostsHelper {
|
|||||||
linkImage: map["link_image"],
|
linkImage: map["link_image"],
|
||||||
likes: map["likes"],
|
likes: map["likes"],
|
||||||
userLike: map["userlike"],
|
userLike: map["userlike"],
|
||||||
access: _APIUserAccessMap[map["user_access"]],
|
access: _APIUserAccessMap[map["user_access"]]!,
|
||||||
comments: comments,
|
comments: comments,
|
||||||
survey: survey);
|
survey: survey);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ const _PreferenceKeysName = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class PreferencesHelper {
|
class PreferencesHelper {
|
||||||
static PreferencesHelper _instance;
|
static PreferencesHelper? _instance;
|
||||||
|
|
||||||
static Future<PreferencesHelper> getInstance() async {
|
static Future<PreferencesHelper> getInstance() async {
|
||||||
if (_instance == null) {
|
if (_instance == null) {
|
||||||
@ -38,10 +38,10 @@ class PreferencesHelper {
|
|||||||
await _init();
|
await _init();
|
||||||
}
|
}
|
||||||
|
|
||||||
return _instance;
|
return _instance!;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SharedPreferences _sharedPreferences;
|
static late SharedPreferences _sharedPreferences;
|
||||||
|
|
||||||
PreferencesHelper._();
|
PreferencesHelper._();
|
||||||
|
|
||||||
@ -50,7 +50,7 @@ class PreferencesHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set new login tokens
|
/// Set new login tokens
|
||||||
Future<void> setLoginToken(String token) async {
|
Future<void> setLoginToken(String? token) async {
|
||||||
if (token != null)
|
if (token != null)
|
||||||
await setString(PreferencesKeyList.LOGIN_TOKEN, token);
|
await setString(PreferencesKeyList.LOGIN_TOKEN, token);
|
||||||
else
|
else
|
||||||
@ -58,7 +58,7 @@ class PreferencesHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get current [LoginTokens]. Returns null if none or in case of failure
|
/// Get current [LoginTokens]. Returns null if none or in case of failure
|
||||||
String getLoginToken() {
|
String? getLoginToken() {
|
||||||
try {
|
try {
|
||||||
final string = getString(PreferencesKeyList.LOGIN_TOKEN);
|
final string = getString(PreferencesKeyList.LOGIN_TOKEN);
|
||||||
return string;
|
return string;
|
||||||
@ -69,35 +69,35 @@ class PreferencesHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool containsKey(PreferencesKeyList key) {
|
bool containsKey(PreferencesKeyList key) {
|
||||||
return _sharedPreferences.containsKey(_PreferenceKeysName[key]);
|
return _sharedPreferences.containsKey(_PreferenceKeysName[key]!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> removeKey(PreferencesKeyList key) async {
|
Future<bool> removeKey(PreferencesKeyList key) async {
|
||||||
return await _sharedPreferences.remove(_PreferenceKeysName[key]);
|
return await _sharedPreferences.remove(_PreferenceKeysName[key]!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> setString(PreferencesKeyList key, String value) async {
|
Future<bool> setString(PreferencesKeyList key, String value) async {
|
||||||
return await _sharedPreferences.setString(_PreferenceKeysName[key], value);
|
return await _sharedPreferences.setString(_PreferenceKeysName[key]!, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
String getString(PreferencesKeyList key) {
|
String? getString(PreferencesKeyList key) {
|
||||||
return _sharedPreferences.getString(_PreferenceKeysName[key]);
|
return _sharedPreferences.getString(_PreferenceKeysName[key]!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> setBool(PreferencesKeyList key, bool value) async {
|
Future<bool> setBool(PreferencesKeyList key, bool value) async {
|
||||||
return await _sharedPreferences.setBool(_PreferenceKeysName[key], value);
|
return await _sharedPreferences.setBool(_PreferenceKeysName[key]!, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> setInt(PreferencesKeyList key, int value) async {
|
Future<bool> setInt(PreferencesKeyList key, int value) async {
|
||||||
return await _sharedPreferences.setInt(_PreferenceKeysName[key], value);
|
return await _sharedPreferences.setInt(_PreferenceKeysName[key]!, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getInt(PreferencesKeyList key) {
|
int? getInt(PreferencesKeyList key) {
|
||||||
return _sharedPreferences.getInt(_PreferenceKeysName[key]);
|
return _sharedPreferences.getInt(_PreferenceKeysName[key]!);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getBool(PreferencesKeyList key, {bool alternative = false}) {
|
bool getBool(PreferencesKeyList key, {bool alternative = false}) {
|
||||||
final v = _sharedPreferences.getBool(_PreferenceKeysName[key]);
|
final v = _sharedPreferences.getBool(_PreferenceKeysName[key]!);
|
||||||
return v == null ? alternative : v;
|
return v == null ? alternative : v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +115,7 @@ class PreferencesHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferencesHelper preferences() {
|
PreferencesHelper? preferences() {
|
||||||
if (PreferencesHelper._instance == null)
|
if (PreferencesHelper._instance == null)
|
||||||
throw Exception("Try to get preference before their initialization!");
|
throw Exception("Try to get preference before their initialization!");
|
||||||
|
|
||||||
|
@ -21,14 +21,14 @@ const _PushNotificationsAPIMap = {
|
|||||||
|
|
||||||
class PushNotificationsHelper {
|
class PushNotificationsHelper {
|
||||||
/// Get cached status of push notifications
|
/// Get cached status of push notifications
|
||||||
static Future<PushNotificationsStatus> getLocalStatus() async {
|
static Future<PushNotificationsStatus?> getLocalStatus() async {
|
||||||
final pref = await PreferencesHelper.getInstance();
|
final pref = await PreferencesHelper.getInstance();
|
||||||
|
|
||||||
if (!pref.containsKey(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS))
|
if (!pref.containsKey(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS))
|
||||||
return PushNotificationsStatus.UNDEFINED;
|
return PushNotificationsStatus.UNDEFINED;
|
||||||
|
|
||||||
return _PushNotificationsAPIMap[
|
return _PushNotificationsAPIMap[
|
||||||
pref.getString(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS)];
|
pref.getString(PreferencesKeyList.PUSH_NOTIFICATIONS_STATUS)!];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Refresh local status with information from server
|
/// Refresh local status with information from server
|
||||||
@ -62,8 +62,8 @@ class PushNotificationsHelper {
|
|||||||
|
|
||||||
/// Configure push notifications
|
/// Configure push notifications
|
||||||
static Future<void> configure(
|
static Future<void> configure(
|
||||||
BuildContext context, PushNotificationsStatus newStatus) async {
|
BuildContext context, PushNotificationsStatus? newStatus) async {
|
||||||
String firebaseToken = "";
|
String? firebaseToken = "";
|
||||||
switch (newStatus) {
|
switch (newStatus) {
|
||||||
case PushNotificationsStatus.DISABLED:
|
case PushNotificationsStatus.DISABLED:
|
||||||
break;
|
break;
|
||||||
@ -90,8 +90,8 @@ class PushNotificationsHelper {
|
|||||||
|
|
||||||
/// Set new push notification status on the server
|
/// Set new push notification status on the server
|
||||||
static Future<void> setNewStatus(
|
static Future<void> setNewStatus(
|
||||||
PushNotificationsStatus newStatus, {
|
PushNotificationsStatus? newStatus, {
|
||||||
String firebaseToken = "",
|
String? firebaseToken = "",
|
||||||
}) async =>
|
}) async =>
|
||||||
await APIRequest.withLogin("push_notifications/configure")
|
await APIRequest.withLogin("push_notifications/configure")
|
||||||
.addString(
|
.addString(
|
||||||
@ -104,6 +104,6 @@ class PushNotificationsHelper {
|
|||||||
|
|
||||||
/// Is true if possible if push notifications are configurable
|
/// Is true if possible if push notifications are configurable
|
||||||
static bool get arePushNotificationsAvailable =>
|
static bool get arePushNotificationsAvailable =>
|
||||||
srvConfig.notificationsPolicy.hasFirebase ||
|
srvConfig!.notificationsPolicy.hasFirebase ||
|
||||||
(isAndroid && srvConfig.notificationsPolicy.hasIndependent);
|
(isAndroid && srvConfig!.notificationsPolicy.hasIndependent);
|
||||||
}
|
}
|
||||||
|
38
lib/helpers/report_helper.dart
Normal file
38
lib/helpers/report_helper.dart
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import 'package:comunic/enums/report_target_type.dart';
|
||||||
|
import 'package:comunic/models/api_request.dart';
|
||||||
|
import 'package:comunic/models/report_target.dart';
|
||||||
|
import 'package:comunic/models/server_config.dart';
|
||||||
|
|
||||||
|
/// Reports Helper
|
||||||
|
///
|
||||||
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
|
enum ReportResult {
|
||||||
|
Success,
|
||||||
|
ErrorAlreadyReported,
|
||||||
|
Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReportHelper {
|
||||||
|
/// Send a new report to the server
|
||||||
|
static Future<ReportResult> sendReport({
|
||||||
|
required ReportCause cause,
|
||||||
|
required ReportTarget target,
|
||||||
|
required String comment,
|
||||||
|
}) async {
|
||||||
|
final response = await APIRequest.withLogin("reports/create", args: {
|
||||||
|
"cause": cause.id,
|
||||||
|
"target_type": target.type.apiId,
|
||||||
|
"target_id": target.id.toString(),
|
||||||
|
"comment": comment
|
||||||
|
}).exec();
|
||||||
|
|
||||||
|
if (response.isOK) return ReportResult.Success;
|
||||||
|
|
||||||
|
print("Failed to send report: ${response.content}");
|
||||||
|
|
||||||
|
if (response.code == 409) return ReportResult.ErrorAlreadyReported;
|
||||||
|
|
||||||
|
return ReportResult.Error;
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@ class SearchHelper {
|
|||||||
/// Search for user. This method returns information about the target users
|
/// Search for user. This method returns information about the target users
|
||||||
///
|
///
|
||||||
/// Returns information about the target users or null if an error occurred
|
/// Returns information about the target users or null if an error occurred
|
||||||
Future<UsersList> searchUser(String query) async {
|
Future<UsersList?> searchUser(String query) async {
|
||||||
// Execute the query on the server
|
// Execute the query on the server
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "user/search", needLogin: true, args: {"query": query}).exec();
|
uri: "user/search", needLogin: true, args: {"query": query}).exec();
|
||||||
@ -21,7 +21,7 @@ class SearchHelper {
|
|||||||
if (response.code != 200) return null;
|
if (response.code != 200) return null;
|
||||||
|
|
||||||
return await UsersHelper()
|
return await UsersHelper()
|
||||||
.getUsersInfo(response.getArray().map((f) => cast<int>(f)).toList());
|
.getUsersInfo(response.getArray()!.map((f) => cast<int>(f)).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Perform a global search
|
/// Perform a global search
|
||||||
@ -31,7 +31,7 @@ class SearchHelper {
|
|||||||
|
|
||||||
result.assertOk();
|
result.assertOk();
|
||||||
|
|
||||||
return SearchResultsList()..addAll(result.getArray().map((f) {
|
return SearchResultsList()..addAll(result.getArray()!.map((f) {
|
||||||
switch (f["kind"]) {
|
switch (f["kind"]) {
|
||||||
case "user":
|
case "user":
|
||||||
return SearchResult(id: f["id"], kind: SearchResultKind.USER);
|
return SearchResult(id: f["id"], kind: SearchResultKind.USER);
|
||||||
|
@ -17,7 +17,7 @@ abstract class SerializableElement<T> extends Comparable<T> {
|
|||||||
|
|
||||||
abstract class BaseSerializationHelper<T extends SerializableElement> {
|
abstract class BaseSerializationHelper<T extends SerializableElement> {
|
||||||
/// List cache
|
/// List cache
|
||||||
List<T> _cache;
|
List<T>? _cache;
|
||||||
|
|
||||||
/// The name of the type of data to serialise
|
/// The name of the type of data to serialise
|
||||||
String get type;
|
String get type;
|
||||||
@ -48,12 +48,15 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
try {
|
try {
|
||||||
final file = await _getFilePath();
|
final file = await _getFilePath();
|
||||||
|
|
||||||
if (!await file.exists()) return _cache = [];
|
if (!await file.exists()) {
|
||||||
|
_cache = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final List<dynamic> json = jsonDecode(await file.readAsString());
|
final List<dynamic> json = jsonDecode(await file.readAsString());
|
||||||
_cache = json.cast<Map<String, dynamic>>().map(parse).toList();
|
_cache = json.cast<Map<String, dynamic>>().map(parse).toList();
|
||||||
|
|
||||||
_cache.sort();
|
_cache!.sort();
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
logError(e, s);
|
logError(e, s);
|
||||||
print("Failed to read serialized data!");
|
print("Failed to read serialized data!");
|
||||||
@ -67,8 +70,10 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final file = await _getFilePath();
|
final file = await _getFilePath();
|
||||||
await file.writeAsString(jsonEncode(
|
await file.writeAsString(jsonEncode(_cache!
|
||||||
_cache.map((e) => e.toJson()).toList().cast<Map<String, dynamic>>()));
|
.map((e) => e.toJson())
|
||||||
|
.toList()
|
||||||
|
.cast<Map<String, dynamic>>()));
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
print("Failed to write file!");
|
print("Failed to write file!");
|
||||||
logError(e, s);
|
logError(e, s);
|
||||||
@ -78,7 +83,7 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
/// Get the current list of elements
|
/// Get the current list of elements
|
||||||
Future<List<T>> getList() async {
|
Future<List<T>> getList() async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
return List.from(_cache);
|
return List.from(_cache!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a new list of conversations
|
/// Set a new list of conversations
|
||||||
@ -90,23 +95,23 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
/// Insert new element
|
/// Insert new element
|
||||||
Future<void> insert(T el) async {
|
Future<void> insert(T el) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
_cache.add(el);
|
_cache!.add(el);
|
||||||
_cache.sort();
|
_cache!.sort();
|
||||||
await _saveCache();
|
await _saveCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert new element
|
/// Insert new element
|
||||||
Future<void> insertMany(List<T> els) async {
|
Future<void> insertMany(List<T> els) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
_cache.addAll(els);
|
_cache!.addAll(els);
|
||||||
_cache.sort();
|
_cache!.sort();
|
||||||
await _saveCache();
|
await _saveCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if any entry in the last match the predicate
|
/// Check if any entry in the last match the predicate
|
||||||
Future<bool> any(bool isContained(T t)) async {
|
Future<bool> any(bool isContained(T t)) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
return _cache.any((element) => isContained(element));
|
return _cache!.any((element) => isContained(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> has(T el) => any((t) => t == el);
|
Future<bool> has(T el) => any((t) => t == el);
|
||||||
@ -114,7 +119,7 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
/// Check if any entry in the last match the predicate
|
/// Check if any entry in the last match the predicate
|
||||||
Future<T> first(bool filter(T t)) async {
|
Future<T> first(bool filter(T t)) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
return _cache.firstWhere((element) => filter(element));
|
return _cache!.firstWhere((element) => filter(element));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace an element with another one
|
/// Replace an element with another one
|
||||||
@ -122,10 +127,10 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
await _loadCache();
|
await _loadCache();
|
||||||
|
|
||||||
// Insert or replace the element
|
// Insert or replace the element
|
||||||
_cache = _cache.where((element) => !isToReplace(element)).toList();
|
_cache = _cache!.where((element) => !isToReplace(element)).toList();
|
||||||
_cache.add(newEl);
|
_cache!.add(newEl);
|
||||||
|
|
||||||
_cache.sort();
|
_cache!.sort();
|
||||||
await _saveCache();
|
await _saveCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,8 +138,8 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
Future<void> insertOrReplaceElements(List<T> list) async {
|
Future<void> insertOrReplaceElements(List<T> list) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
|
|
||||||
_cache.removeWhere((element) => list.any((newEl) => element == newEl));
|
_cache!.removeWhere((element) => list.any((newEl) => element == newEl));
|
||||||
_cache.addAll(list);
|
_cache!.addAll(list);
|
||||||
|
|
||||||
await _saveCache();
|
await _saveCache();
|
||||||
}
|
}
|
||||||
@ -142,7 +147,7 @@ abstract class BaseSerializationHelper<T extends SerializableElement> {
|
|||||||
/// Remove elements
|
/// Remove elements
|
||||||
Future<void> removeElement(bool isToRemove(T t)) async {
|
Future<void> removeElement(bool isToRemove(T t)) async {
|
||||||
await _loadCache();
|
await _loadCache();
|
||||||
_cache.removeWhere((element) => isToRemove(element));
|
_cache!.removeWhere((element) => isToRemove(element));
|
||||||
await _saveCache();
|
await _saveCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,23 +8,22 @@ import 'package:comunic/models/conversation_message.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
HashMap<int, ConversationsMessagesSerializationHelper> _instances;
|
HashMap<int?, ConversationsMessagesSerializationHelper>? _instances;
|
||||||
|
|
||||||
class ConversationsMessagesSerializationHelper
|
class ConversationsMessagesSerializationHelper
|
||||||
extends BaseSerializationHelper<ConversationMessage> {
|
extends BaseSerializationHelper<ConversationMessage> {
|
||||||
final int convID;
|
final int convID;
|
||||||
|
|
||||||
ConversationsMessagesSerializationHelper._(int convID)
|
ConversationsMessagesSerializationHelper._(int convID)
|
||||||
: convID = convID,
|
: convID = convID;
|
||||||
assert(convID != null);
|
|
||||||
|
|
||||||
factory ConversationsMessagesSerializationHelper(int convID) {
|
factory ConversationsMessagesSerializationHelper(int? convID) {
|
||||||
if (_instances == null) _instances = HashMap();
|
if (_instances == null) _instances = HashMap();
|
||||||
|
|
||||||
if (!_instances.containsKey(convID))
|
if (!_instances!.containsKey(convID))
|
||||||
_instances[convID] = ConversationsMessagesSerializationHelper._(convID);
|
_instances![convID] = ConversationsMessagesSerializationHelper._(convID!);
|
||||||
|
|
||||||
return _instances[convID];
|
return _instances![convID]!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -28,5 +28,5 @@ class ConversationsSerializationHelper
|
|||||||
ConversationsList()..addAll(await super.getList());
|
ConversationsList()..addAll(await super.getList());
|
||||||
|
|
||||||
/// Get a conversation
|
/// Get a conversation
|
||||||
Future<Conversation> get(int id) => first((t) => t.id == id);
|
Future<Conversation> get(int? id) => first((t) => t.id == id);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import 'package:comunic/models/user.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
UsersListSerialisationHelper _singleton;
|
UsersListSerialisationHelper? _singleton;
|
||||||
|
|
||||||
class UsersListSerialisationHelper extends BaseSerializationHelper<User> {
|
class UsersListSerialisationHelper extends BaseSerializationHelper<User> {
|
||||||
UsersListSerialisationHelper._();
|
UsersListSerialisationHelper._();
|
||||||
@ -13,7 +13,7 @@ class UsersListSerialisationHelper extends BaseSerializationHelper<User> {
|
|||||||
factory UsersListSerialisationHelper() {
|
factory UsersListSerialisationHelper() {
|
||||||
if (_singleton == null) _singleton = UsersListSerialisationHelper._();
|
if (_singleton == null) _singleton = UsersListSerialisationHelper._();
|
||||||
|
|
||||||
return _singleton;
|
return _singleton!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -23,6 +23,6 @@ class UsersListSerialisationHelper extends BaseSerializationHelper<User> {
|
|||||||
User parse(Map<String, dynamic> m) => User.fromJson(m);
|
User parse(Map<String, dynamic> m) => User.fromJson(m);
|
||||||
|
|
||||||
/// Remove a user by its ID
|
/// Remove a user by its ID
|
||||||
Future<void> removeUserByID(int userID) =>
|
Future<void> removeUserByID(int? userID) =>
|
||||||
removeElement((t) => t.id == userID);
|
removeElement((t) => t.id == userID);
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import 'package:version/version.dart';
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class ServerConfigurationHelper {
|
class ServerConfigurationHelper {
|
||||||
static ServerConfig _config;
|
static ServerConfig? _config;
|
||||||
|
|
||||||
/// Make sure the configuration has been correctly loaded
|
/// Make sure the configuration has been correctly loaded
|
||||||
static Future<void> ensureLoaded() async {
|
static Future<void> ensureLoaded() async {
|
||||||
@ -17,11 +17,13 @@ class ServerConfigurationHelper {
|
|||||||
(await APIRequest.withoutLogin("server/config").execWithThrow())
|
(await APIRequest.withoutLogin("server/config").execWithThrow())
|
||||||
.getObject();
|
.getObject();
|
||||||
|
|
||||||
|
final banner = response["banner"];
|
||||||
final pushNotificationsPolicy = response["push_notifications"];
|
final pushNotificationsPolicy = response["push_notifications"];
|
||||||
final passwordPolicy = response["password_policy"];
|
final passwordPolicy = response["password_policy"];
|
||||||
final dataConservationPolicy = response["data_conservation_policy"];
|
final dataConservationPolicy = response["data_conservation_policy"];
|
||||||
final conversationsPolicy = response["conversations_policy"];
|
final conversationsPolicy = response["conversations_policy"];
|
||||||
final accountInformationPolicy = response["account_info_policy"];
|
final accountInformationPolicy = response["account_info_policy"];
|
||||||
|
final reportPolicy = response["report_policy"];
|
||||||
|
|
||||||
_config = ServerConfig(
|
_config = ServerConfig(
|
||||||
minSupportedMobileVersion:
|
minSupportedMobileVersion:
|
||||||
@ -31,6 +33,15 @@ class ServerConfigurationHelper {
|
|||||||
contactEmail: response["contact_email"],
|
contactEmail: response["contact_email"],
|
||||||
playStoreURL: response["play_store_url"],
|
playStoreURL: response["play_store_url"],
|
||||||
androidDirectDownloadURL: response["android_direct_download_url"],
|
androidDirectDownloadURL: response["android_direct_download_url"],
|
||||||
|
banner: banner == null
|
||||||
|
? null
|
||||||
|
: Banner(
|
||||||
|
enabled: banner["enabled"],
|
||||||
|
expire: banner["expire"],
|
||||||
|
nature: BannerNatureExt.fromStr(banner["nature"]),
|
||||||
|
message: Map<String, dynamic>.from(banner["message"])
|
||||||
|
.map((key, value) => MapEntry(key, value.toString())),
|
||||||
|
link: banner["link"]),
|
||||||
notificationsPolicy: NotificationsPolicy(
|
notificationsPolicy: NotificationsPolicy(
|
||||||
hasFirebase: pushNotificationsPolicy["has_firebase"],
|
hasFirebase: pushNotificationsPolicy["has_firebase"],
|
||||||
hasIndependent: pushNotificationsPolicy["has_independent"],
|
hasIndependent: pushNotificationsPolicy["has_independent"],
|
||||||
@ -70,7 +81,8 @@ class ServerConfigurationHelper {
|
|||||||
writingEventInterval: conversationsPolicy["writing_event_interval"],
|
writingEventInterval: conversationsPolicy["writing_event_interval"],
|
||||||
writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
|
writingEventLifetime: conversationsPolicy["writing_event_lifetime"],
|
||||||
maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
|
maxMessageImageWidth: conversationsPolicy["max_message_image_width"],
|
||||||
maxMessageImageHeight: conversationsPolicy["max_message_image_height"],
|
maxMessageImageHeight:
|
||||||
|
conversationsPolicy["max_message_image_height"],
|
||||||
maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
|
maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"],
|
||||||
maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
|
maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"],
|
||||||
maxLogoWidth: conversationsPolicy["max_logo_width"],
|
maxLogoWidth: conversationsPolicy["max_logo_width"],
|
||||||
@ -83,11 +95,22 @@ class ServerConfigurationHelper {
|
|||||||
maxLastNameLength: accountInformationPolicy["max_last_name_length"],
|
maxLastNameLength: accountInformationPolicy["max_last_name_length"],
|
||||||
maxLocationLength: accountInformationPolicy["max_location_length"],
|
maxLocationLength: accountInformationPolicy["max_location_length"],
|
||||||
),
|
),
|
||||||
);
|
reportPolicy: reportPolicy == null
|
||||||
|
? null
|
||||||
|
: ReportPolicy(
|
||||||
|
causes: List.from(reportPolicy["causes"]
|
||||||
|
.map((cause) => ReportCause(
|
||||||
|
id: cause["id"],
|
||||||
|
label: new Map<String, String>.from(cause["label"])))
|
||||||
|
.toList()),
|
||||||
|
maxCommentLength: reportPolicy["max_comment_length"],
|
||||||
|
canUserReportHisOwnContent:
|
||||||
|
reportPolicy["can_user_report_his_own_content"],
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current server configuration, throwing if it is not loaded yet
|
/// Get current server configuration, throwing if it is not loaded yet
|
||||||
static ServerConfig get config {
|
static ServerConfig? get config {
|
||||||
if (_config == null)
|
if (_config == null)
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Trying to access server configuration but it is not loaded yet!");
|
"Trying to access server configuration but it is not loaded yet!");
|
||||||
@ -97,4 +120,6 @@ class ServerConfigurationHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Shortcut for server configuration
|
/// Shortcut for server configuration
|
||||||
ServerConfig get srvConfig => ServerConfigurationHelper.config;
|
ServerConfig? get srvConfig => ServerConfigurationHelper.config;
|
||||||
|
|
||||||
|
bool get showBanner => srvConfig!.banner != null && srvConfig!.banner!.visible;
|
||||||
|
@ -94,7 +94,7 @@ class SettingsHelper {
|
|||||||
hasImage: response["has_image"],
|
hasImage: response["has_image"],
|
||||||
imageURL: response["image_url"],
|
imageURL: response["image_url"],
|
||||||
visibility:
|
visibility:
|
||||||
_APIAccountImageVisibilityAPILevels[response["visibility"]]);
|
_APIAccountImageVisibilityAPILevels[response["visibility"]]!);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Upload a new account image
|
/// Upload a new account image
|
||||||
@ -143,7 +143,7 @@ class SettingsHelper {
|
|||||||
/// Delete a custom emoji
|
/// Delete a custom emoji
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> deleteCustomEmoji(int emojiID) async =>
|
static Future<void> deleteCustomEmoji(int? emojiID) async =>
|
||||||
(await APIRequest(uri: "settings/delete_custom_emoji", needLogin: true)
|
(await APIRequest(uri: "settings/delete_custom_emoji", needLogin: true)
|
||||||
.addInt("emojiID", emojiID)
|
.addInt("emojiID", emojiID)
|
||||||
.exec())
|
.exec())
|
||||||
@ -223,7 +223,7 @@ class SettingsHelper {
|
|||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
static Future<void> setDataConservationPolicy(
|
static Future<void> setDataConservationPolicy(
|
||||||
String password, DataConservationPolicySettings newSettings) async {
|
String? password, DataConservationPolicySettings newSettings) async {
|
||||||
await APIRequest(
|
await APIRequest(
|
||||||
uri: "settings/set_data_conservation_policy", needLogin: true)
|
uri: "settings/set_data_conservation_policy", needLogin: true)
|
||||||
.addString("password", password)
|
.addString("password", password)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:comunic/models/survey.dart';
|
import 'package:comunic/models/survey.dart';
|
||||||
import 'package:comunic/models/survey_choice.dart';
|
import 'package:comunic/models/survey_choice.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Survey helper
|
/// Survey helper
|
||||||
///
|
///
|
||||||
@ -26,9 +25,7 @@ class SurveyHelper {
|
|||||||
|
|
||||||
/// Send the response of a user to a survey
|
/// Send the response of a user to a survey
|
||||||
Future<bool> respondToSurvey(
|
Future<bool> respondToSurvey(
|
||||||
{@required Survey survey, @required SurveyChoice choice}) async {
|
{required Survey survey, required SurveyChoice choice}) async {
|
||||||
assert(survey != null);
|
|
||||||
assert(choice != null);
|
|
||||||
|
|
||||||
return (await APIRequest(
|
return (await APIRequest(
|
||||||
uri: "surveys/send_response",
|
uri: "surveys/send_response",
|
||||||
|
@ -23,7 +23,7 @@ enum GetUserAdvancedInformationErrorCause {
|
|||||||
class GetUserAdvancedUserError extends Error {
|
class GetUserAdvancedUserError extends Error {
|
||||||
final GetUserAdvancedInformationErrorCause cause;
|
final GetUserAdvancedInformationErrorCause cause;
|
||||||
|
|
||||||
GetUserAdvancedUserError(this.cause) : assert(cause != null);
|
GetUserAdvancedUserError(this.cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UsersHelper {
|
class UsersHelper {
|
||||||
@ -31,7 +31,7 @@ class UsersHelper {
|
|||||||
///
|
///
|
||||||
/// Return the list of users information in case of success, null in case of
|
/// Return the list of users information in case of success, null in case of
|
||||||
/// failure
|
/// failure
|
||||||
Future<UsersList> _downloadInfo(List<int> users) async {
|
Future<UsersList?> _downloadInfo(List<int?> users) async {
|
||||||
// Execute the request
|
// Execute the request
|
||||||
final response = await APIRequest(
|
final response = await APIRequest(
|
||||||
uri: "user/getInfoMultiple",
|
uri: "user/getInfoMultiple",
|
||||||
@ -69,7 +69,7 @@ class UsersHelper {
|
|||||||
|
|
||||||
/// Get users information from a given [Set]. Throws an exception in case
|
/// Get users information from a given [Set]. Throws an exception in case
|
||||||
/// of failure
|
/// of failure
|
||||||
Future<UsersList> getListWithThrow(Set<int> users,
|
Future<UsersList> getListWithThrow(Set<int?> users,
|
||||||
{bool forceDownload = false}) async {
|
{bool forceDownload = false}) async {
|
||||||
final list =
|
final list =
|
||||||
await getUsersInfo(users.toList(), forceDownload: forceDownload);
|
await getUsersInfo(users.toList(), forceDownload: forceDownload);
|
||||||
@ -82,16 +82,16 @@ class UsersHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get information about a single user. Throws in case of failure
|
/// Get information about a single user. Throws in case of failure
|
||||||
Future<User> getSingleWithThrow(int user,
|
Future<User> getSingleWithThrow(int? user,
|
||||||
{bool forceDownload = false}) async {
|
{bool forceDownload = false}) async {
|
||||||
return (await getListWithThrow(Set<int>()..add(user),
|
return (await getListWithThrow(Set<int?>()..add(user),
|
||||||
forceDownload: forceDownload))[0];
|
forceDownload: forceDownload))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get users information from a given [Set]
|
/// Get users information from a given [Set]
|
||||||
///
|
///
|
||||||
/// Throws in case of failure
|
/// Throws in case of failure
|
||||||
Future<UsersList> getList(Set<int> users,
|
Future<UsersList> getList(Set<int?> users,
|
||||||
{bool forceDownload = false}) async {
|
{bool forceDownload = false}) async {
|
||||||
final list = await getUsersInfo(users.toList());
|
final list = await getUsersInfo(users.toList());
|
||||||
|
|
||||||
@ -104,13 +104,13 @@ class UsersHelper {
|
|||||||
///
|
///
|
||||||
/// If [forceDownload] is set to true, the data will always be retrieved from
|
/// If [forceDownload] is set to true, the data will always be retrieved from
|
||||||
/// the server, otherwise cached data will be used if available
|
/// the server, otherwise cached data will be used if available
|
||||||
Future<UsersList> getUsersInfo(List<int> users,
|
Future<UsersList?> getUsersInfo(List<int?> users,
|
||||||
{bool forceDownload = false}) async {
|
{bool forceDownload = false}) async {
|
||||||
List<int> toDownload = [];
|
List<int?> toDownload = [];
|
||||||
UsersList list = UsersList();
|
UsersList list = UsersList();
|
||||||
|
|
||||||
// Check cache
|
// Check cache
|
||||||
for (int userID in users) {
|
for (int? userID in users) {
|
||||||
if (!forceDownload &&
|
if (!forceDownload &&
|
||||||
await UsersListSerialisationHelper().any((u) => u.id == userID))
|
await UsersListSerialisationHelper().any((u) => u.id == userID))
|
||||||
list.add(
|
list.add(
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import 'package:comunic/utils/flutter_utils.dart';
|
import 'package:comunic/utils/flutter_utils.dart';
|
||||||
import 'package:package_info/package_info.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:version/version.dart';
|
import 'package:version/version.dart';
|
||||||
|
|
||||||
/// Application version helper
|
/// Application version helper
|
||||||
@ -7,15 +7,15 @@ import 'package:version/version.dart';
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class VersionHelper {
|
class VersionHelper {
|
||||||
static PackageInfo _info;
|
static PackageInfo? _info;
|
||||||
|
|
||||||
static Future<void> ensureLoaded() async {
|
static Future<void> ensureLoaded() async {
|
||||||
if (!isWeb) _info = await PackageInfo.fromPlatform();
|
if (!isWeb) _info = await PackageInfo.fromPlatform();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current version information
|
/// Get current version information
|
||||||
static PackageInfo get info => _info;
|
static PackageInfo? get info => _info;
|
||||||
|
|
||||||
/// Get current application version, in parsed format
|
/// Get current application version, in parsed format
|
||||||
static Version get version => Version.parse(info.version);
|
static Version get version => Version.parse(info!.version);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:comunic/models/api_request.dart';
|
import 'package:comunic/models/api_request.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
/// Virtual directory helper
|
/// Virtual directory helper
|
||||||
///
|
///
|
||||||
@ -9,12 +8,12 @@ enum VirtualDirectoryType { USER, GROUP, NONE }
|
|||||||
|
|
||||||
class VirtualDirectoryResult {
|
class VirtualDirectoryResult {
|
||||||
final VirtualDirectoryType type;
|
final VirtualDirectoryType type;
|
||||||
final int id;
|
final int? id;
|
||||||
|
|
||||||
const VirtualDirectoryResult({
|
const VirtualDirectoryResult({
|
||||||
@required this.type,
|
required this.type,
|
||||||
this.id,
|
this.id,
|
||||||
}) : assert(type != null);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class VirtualDirectoryHelper {
|
class VirtualDirectoryHelper {
|
||||||
@ -43,7 +42,6 @@ class VirtualDirectoryHelper {
|
|||||||
default:
|
default:
|
||||||
throw Exception("Unsupported virtual directory kind: $kind");
|
throw Exception("Unsupported virtual directory kind: $kind");
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Exception("Could not get virtual directory!");
|
throw new Exception("Could not get virtual directory!");
|
||||||
|
@ -15,7 +15,7 @@ class WebAppHelper {
|
|||||||
static Future<MembershipList> getMemberships() async {
|
static Future<MembershipList> getMemberships() async {
|
||||||
final response =
|
final response =
|
||||||
(await APIRequest.withLogin("webApp/getMemberships").execWithThrow())
|
(await APIRequest.withLogin("webApp/getMemberships").execWithThrow())
|
||||||
.getArray();
|
.getArray()!;
|
||||||
|
|
||||||
return MembershipList()
|
return MembershipList()
|
||||||
..addAll(response
|
..addAll(response
|
||||||
@ -26,7 +26,7 @@ class WebAppHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Turn an API entry into a membership entry
|
/// Turn an API entry into a membership entry
|
||||||
static Membership _apiToMembership(Map<String, dynamic> entry) {
|
static Membership? _apiToMembership(Map<String, dynamic> entry) {
|
||||||
switch (entry["type"]) {
|
switch (entry["type"]) {
|
||||||
case "conversation":
|
case "conversation":
|
||||||
return Membership.conversation(
|
return Membership.conversation(
|
||||||
|
@ -15,7 +15,7 @@ import 'package:web_socket_channel/web_socket_channel.dart';
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class WebSocketHelper {
|
class WebSocketHelper {
|
||||||
static WebSocketChannel _ws;
|
static WebSocketChannel? _ws;
|
||||||
|
|
||||||
static int _counter = 0;
|
static int _counter = 0;
|
||||||
|
|
||||||
@ -23,11 +23,11 @@ class WebSocketHelper {
|
|||||||
|
|
||||||
/// Check out whether we are currently connected to WebSocket or not
|
/// Check out whether we are currently connected to WebSocket or not
|
||||||
static bool isConnected() {
|
static bool isConnected() {
|
||||||
return _ws != null && _ws.closeCode == null;
|
return _ws != null && _ws!.closeCode == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get WebSocket access token
|
/// Get WebSocket access token
|
||||||
static Future<String> _getWsToken() async =>
|
static Future<String?> _getWsToken() async =>
|
||||||
(await APIRequest(uri: "ws/token", needLogin: true).exec())
|
(await APIRequest(uri: "ws/token", needLogin: true).exec())
|
||||||
.assertOk()
|
.assertOk()
|
||||||
.getObject()["token"];
|
.getObject()["token"];
|
||||||
@ -47,7 +47,7 @@ class WebSocketHelper {
|
|||||||
// Connect
|
// Connect
|
||||||
_ws = WebSocketChannel.connect(wsURI);
|
_ws = WebSocketChannel.connect(wsURI);
|
||||||
|
|
||||||
_ws.stream.listen(
|
_ws!.stream.listen(
|
||||||
// When we got data
|
// When we got data
|
||||||
(data) {
|
(data) {
|
||||||
print("WS New data: $data");
|
print("WS New data: $data");
|
||||||
@ -75,7 +75,7 @@ class WebSocketHelper {
|
|||||||
|
|
||||||
/// Close current WebSocket (if any)
|
/// Close current WebSocket (if any)
|
||||||
static close() {
|
static close() {
|
||||||
if (isConnected()) _ws.sink.close();
|
if (isConnected()) _ws!.sink.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a new message
|
/// Send a new message
|
||||||
@ -93,7 +93,7 @@ class WebSocketHelper {
|
|||||||
|
|
||||||
print("WS Send message: $msg");
|
print("WS Send message: $msg");
|
||||||
|
|
||||||
_ws.sink.add(msg);
|
_ws!.sink.add(msg);
|
||||||
|
|
||||||
_requests[id] = completer;
|
_requests[id] = completer;
|
||||||
return completer.future;
|
return completer.future;
|
||||||
@ -240,11 +240,11 @@ class WebSocketHelper {
|
|||||||
|
|
||||||
// Handles errors
|
// Handles errors
|
||||||
if (msg.title != "success") {
|
if (msg.title != "success") {
|
||||||
completer.completeError(Exception("Could not process request!"));
|
completer!.completeError(Exception("Could not process request!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
completer.complete(msg.data);
|
completer!.complete(msg.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,4 +16,7 @@ class AbstractList<E> extends ListBase<E> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void operator []=(int index, E value) => _list[index] = value;
|
void operator []=(int index, E value) => _list[index] = value;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void add(E element) => _list.add(element);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ class BaseSet<T> extends SetBase<T> {
|
|||||||
bool add(T value) => _set.add(value);
|
bool add(T value) => _set.add(value);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool contains(Object element) => _set.contains(element);
|
bool contains(Object? element) => _set.contains(element);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterator<T> get iterator => _set.iterator;
|
Iterator<T> get iterator => _set.iterator;
|
||||||
@ -20,10 +20,10 @@ class BaseSet<T> extends SetBase<T> {
|
|||||||
int get length => _set.length;
|
int get length => _set.length;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
T lookup(Object element) => _set.lookup(element);
|
T? lookup(Object? element) => _set.lookup(element);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool remove(Object value) => _set.remove(value);
|
bool remove(Object? value) => _set.remove(value);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<T> toSet() => _set.toSet();
|
Set<T> toSet() => _set.toSet();
|
||||||
|
@ -10,10 +10,10 @@ class CallMembersList extends AbstractList<CallMember> {
|
|||||||
Set<int> get usersID => this.map((f) => f.userID).toSet();
|
Set<int> get usersID => this.map((f) => f.userID).toSet();
|
||||||
|
|
||||||
/// Remove a specific member from this list
|
/// Remove a specific member from this list
|
||||||
void removeUser(int userID) => this.removeWhere((f) => f.userID == userID);
|
void removeUser(int? userID) => this.removeWhere((f) => f.userID == userID);
|
||||||
|
|
||||||
/// Get the connection of a specific user
|
/// Get the connection of a specific user
|
||||||
CallMember getUser(int userID) => this.firstWhere((f) => f.userID == userID);
|
CallMember getUser(int? userID) => this.firstWhere((f) => f.userID == userID);
|
||||||
|
|
||||||
/// Extract ready peers from this list
|
/// Extract ready peers from this list
|
||||||
CallMembersList get readyPeers =>
|
CallMembersList get readyPeers =>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:collection';
|
import 'package:comunic/lists/abstract_list.dart';
|
||||||
|
|
||||||
import 'package:comunic/models/comment.dart';
|
import 'package:comunic/models/comment.dart';
|
||||||
|
|
||||||
/// Comments list
|
/// Comments list
|
||||||
@ -8,19 +7,7 @@ import 'package:comunic/models/comment.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class CommentsList extends ListBase<Comment> {
|
class CommentsList extends AbstractList<Comment> {
|
||||||
List<Comment> _list = [];
|
|
||||||
|
|
||||||
int get length => _list.length;
|
|
||||||
|
|
||||||
set length(int l) => _list.length = l;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Comment operator [](int index) => _list[index];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void operator []=(int index, Comment value) => _list[index] = value;
|
|
||||||
|
|
||||||
/// Get the list of users in this comments, as a set
|
/// Get the list of users in this comments, as a set
|
||||||
Set<int> get usersID => map((f) => f.userID).toSet();
|
Set<int> get usersID => map((f) => f.userID).toSet();
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,14 @@
|
|||||||
import 'dart:collection';
|
import 'package:comunic/lists/abstract_list.dart';
|
||||||
|
|
||||||
import 'package:comunic/models/conversation_message.dart';
|
import 'package:comunic/models/conversation_message.dart';
|
||||||
|
|
||||||
/// Conversations messages list
|
/// Conversations messages list
|
||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class ConversationMessagesList extends ListBase<ConversationMessage> {
|
class ConversationMessagesList extends AbstractList<ConversationMessage> {
|
||||||
final List<ConversationMessage> _list = [];
|
|
||||||
|
|
||||||
set length(int v) => _list.length = v;
|
|
||||||
|
|
||||||
int get length => _list.length;
|
|
||||||
|
|
||||||
@override
|
|
||||||
ConversationMessage operator [](int index) {
|
|
||||||
return _list[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void operator []=(int index, ConversationMessage value) {
|
|
||||||
_list[index] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the list of the users ID who own a message in this list
|
/// Get the list of the users ID who own a message in this list
|
||||||
Set<int> getUsersID() {
|
Set<int?> getUsersID() {
|
||||||
final Set<int> users = Set();
|
final Set<int?> users = Set();
|
||||||
|
|
||||||
for (ConversationMessage message in this) users.addAll(message.usersID);
|
for (ConversationMessage message in this) users.addAll(message.usersID);
|
||||||
|
|
||||||
@ -33,18 +16,18 @@ class ConversationMessagesList extends ListBase<ConversationMessage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the ID of the last message present in this list
|
/// Get the ID of the last message present in this list
|
||||||
int get lastMessageID {
|
int? get lastMessageID {
|
||||||
int lastMessageID = 0;
|
int? lastMessageID = 0;
|
||||||
for (ConversationMessage message in this)
|
for (ConversationMessage message in this)
|
||||||
if (message.id > lastMessageID) lastMessageID = message.id;
|
if (message.id! > lastMessageID!) lastMessageID = message.id;
|
||||||
return lastMessageID;
|
return lastMessageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the ID of the first message present in this list
|
/// Get the ID of the first message present in this list
|
||||||
int get firstMessageID {
|
int? get firstMessageID {
|
||||||
int firstMessageID = this[0].id;
|
int? firstMessageID = this[0].id;
|
||||||
for (ConversationMessage message in this)
|
for (ConversationMessage message in this)
|
||||||
if (message.id < firstMessageID) firstMessageID = message.id;
|
if (message.id! < firstMessageID!) firstMessageID = message.id;
|
||||||
return firstMessageID;
|
return firstMessageID;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,5 +38,5 @@ class ConversationMessagesList extends ListBase<ConversationMessage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Remove a message from this list
|
/// Remove a message from this list
|
||||||
void removeMsg(int id) => removeWhere((f) => f.id == id);
|
void removeMsg(int? id) => removeWhere((f) => f.id == id);
|
||||||
}
|
}
|
||||||
|
@ -22,12 +22,15 @@ class ConversationsList extends ListBase<Conversation> {
|
|||||||
/// Get the entire lists of users ID in this list
|
/// Get the entire lists of users ID in this list
|
||||||
Set<int> get allUsersID {
|
Set<int> get allUsersID {
|
||||||
final Set<int> list = Set();
|
final Set<int> list = Set();
|
||||||
forEach((c) => c.members.forEach((member) => list.add(member.userID)));
|
forEach((c) => c.members!.forEach((member) => list.add(member.userID)));
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the entire lists of groups ID in this list
|
/// Get the entire lists of groups ID in this list
|
||||||
Set<int> get allGroupsID => where((element) => element.isGroupConversation)
|
Set<int?> get allGroupsID => where((element) => element.isGroupConversation)
|
||||||
.map((e) => e.groupID)
|
.map((e) => e.groupID)
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void add(Conversation element) => _list.add(element);
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,7 @@ import 'package:comunic/models/custom_emoji.dart';
|
|||||||
|
|
||||||
class CustomEmojiesList extends AbstractList<CustomEmoji> {
|
class CustomEmojiesList extends AbstractList<CustomEmoji> {
|
||||||
/// Check if an emoji, identified by its shortcut, is present in this list
|
/// Check if an emoji, identified by its shortcut, is present in this list
|
||||||
bool hasShortcut(String shortcut) =>
|
bool hasShortcut(String shortcut) => any((f) => f.shortcut == shortcut);
|
||||||
firstWhere((f) => f.shortcut == shortcut, orElse: () => null) != null;
|
|
||||||
|
|
||||||
/// Serialize this list
|
/// Serialize this list
|
||||||
List<Map<String, dynamic>> toSerializableList() =>
|
List<Map<String, dynamic>> toSerializableList() =>
|
||||||
|
@ -7,7 +7,7 @@ import 'package:comunic/models/forez_presence.dart';
|
|||||||
|
|
||||||
class PresenceSet extends BaseSet<Presence> {
|
class PresenceSet extends BaseSet<Presence> {
|
||||||
/// Get the presence of a specific user
|
/// Get the presence of a specific user
|
||||||
PresenceSet getForUser(int userID) =>
|
PresenceSet getForUser(int? userID) =>
|
||||||
PresenceSet()..addAll(where((element) => element.userID == userID));
|
PresenceSet()..addAll(where((element) => element.userID == userID));
|
||||||
|
|
||||||
bool containsDate(DateTime dt) => any(
|
bool containsDate(DateTime dt) => any(
|
||||||
@ -24,11 +24,11 @@ class PresenceSet extends BaseSet<Presence> {
|
|||||||
element.day == dt.day,
|
element.day == dt.day,
|
||||||
);
|
);
|
||||||
|
|
||||||
void toggleDate(DateTime dt, int userID) {
|
void toggleDate(DateTime dt, int? userID) {
|
||||||
if (containsDate(dt))
|
if (containsDate(dt))
|
||||||
removeDate(dt);
|
removeDate(dt);
|
||||||
else
|
else
|
||||||
add(Presence.fromDateTime(dt, userID));
|
add(Presence.fromDateTime(dt, userID!));
|
||||||
}
|
}
|
||||||
|
|
||||||
int countAtDate(DateTime dt) => where(
|
int countAtDate(DateTime dt) => where(
|
||||||
|
@ -1,24 +1,11 @@
|
|||||||
import 'dart:collection';
|
import 'package:comunic/lists/abstract_list.dart';
|
||||||
|
|
||||||
import 'package:comunic/models/friend.dart';
|
import 'package:comunic/models/friend.dart';
|
||||||
|
|
||||||
/// List of friends of the user
|
/// List of friends of the user
|
||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class FriendsList extends ListBase<Friend> {
|
class FriendsList extends AbstractList<Friend> {
|
||||||
List<Friend> _list = [];
|
|
||||||
|
|
||||||
int get length => _list.length;
|
|
||||||
|
|
||||||
set length(int length) => _list.length = length;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Friend operator [](int index) => _list[index];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void operator []=(int index, Friend value) => _list[index] = value;
|
|
||||||
|
|
||||||
/// Get the ID of all the friends of the current user
|
/// Get the ID of all the friends of the current user
|
||||||
List<int> get usersId => map((f) => f.id).toList();
|
List<int> get usersId => map((f) => f.id).toList();
|
||||||
}
|
}
|
||||||
|
@ -6,23 +6,23 @@ import 'package:comunic/models/group.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class GroupsList extends MapBase<int, Group> {
|
class GroupsList extends MapBase<int?, Group> {
|
||||||
final Map<int, Group> _groups = Map();
|
final Map<int?, Group?> _groups = Map();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Group operator [](Object key) => _groups[key];
|
Group? operator [](Object? key) => _groups[key];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void operator []=(int key, Group value) => _groups[key] = value;
|
void operator []=(int? key, Group? value) => _groups[key] = value;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void clear() => _groups.clear();
|
void clear() => _groups.clear();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterable<int> get keys => _groups.keys;
|
Iterable<int?> get keys => _groups.keys;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Group remove(Object key) => _groups.remove(key);
|
Group? remove(Object? key) => _groups.remove(key);
|
||||||
|
|
||||||
Group getGroup(int id) => this[id];
|
Group? getGroup(int? id) => this[id];
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,20 @@ import 'package:comunic/models/membership.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class MembershipList extends AbstractList<Membership> {
|
class MembershipList extends AbstractList<Membership?> {
|
||||||
/// Get the IDs of all the users included in some way in this list
|
/// Get the IDs of all the users included in some way in this list
|
||||||
Set<int> get usersId {
|
Set<int?> get usersId {
|
||||||
final s = Set<int>();
|
final s = Set<int?>();
|
||||||
|
|
||||||
forEach((m) {
|
forEach((m) {
|
||||||
switch (m.type) {
|
switch (m!.type) {
|
||||||
case MembershipType.FRIEND:
|
case MembershipType.FRIEND:
|
||||||
s.add(m.friend.id);
|
s.add(m.friend!.id);
|
||||||
break;
|
break;
|
||||||
case MembershipType.GROUP:
|
case MembershipType.GROUP:
|
||||||
break;
|
break;
|
||||||
case MembershipType.CONVERSATION:
|
case MembershipType.CONVERSATION:
|
||||||
s.addAll(m.conversation.membersID);
|
s.addAll(m.conversation!.membersID);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -27,16 +27,16 @@ class MembershipList extends AbstractList<Membership> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the ID of the groups included in this list
|
/// Get the ID of the groups included in this list
|
||||||
Set<int> get groupsId => where((f) => f.type == MembershipType.GROUP)
|
Set<int?> get groupsId => where((f) => f!.type == MembershipType.GROUP)
|
||||||
.map((f) => f.groupID)
|
.map((f) => f!.groupID)
|
||||||
.toSet();
|
.toSet();
|
||||||
|
|
||||||
/// Remove a friend membership from the list
|
/// Remove a friend membership from the list
|
||||||
void removeFriend(int friendID) => remove(firstWhere(
|
void removeFriend(int friendID) => remove(firstWhere(
|
||||||
(f) => f.type == MembershipType.FRIEND && f.friend.id == friendID));
|
(f) => f!.type == MembershipType.FRIEND && f.friend!.id == friendID));
|
||||||
|
|
||||||
/// Get the list of conversations of a group
|
/// Get the list of conversations of a group
|
||||||
Set<Membership> getGroupConversations(int groupID) => where((element) =>
|
Set<Membership?> getGroupConversations(int groupID) => where((element) =>
|
||||||
element.type == MembershipType.CONVERSATION &&
|
element!.type == MembershipType.CONVERSATION &&
|
||||||
element.conversation.groupID == groupID).toSet();
|
element.conversation!.groupID == groupID).toSet();
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@ import 'package:comunic/models/notification.dart';
|
|||||||
class NotificationsList extends AbstractList<Notification> {
|
class NotificationsList extends AbstractList<Notification> {
|
||||||
/// Get the ID of all the users related to the notifications
|
/// Get the ID of all the users related to the notifications
|
||||||
/// included in the list
|
/// included in the list
|
||||||
Set<int> get usersIds {
|
Set<int?> get usersIds {
|
||||||
final list = Set<int>();
|
final list = Set<int?>();
|
||||||
|
|
||||||
forEach((n) {
|
forEach((n) {
|
||||||
list.add(n.fromUser);
|
list.add(n.fromUser);
|
||||||
@ -28,8 +28,8 @@ class NotificationsList extends AbstractList<Notification> {
|
|||||||
|
|
||||||
/// Get the ID of all the groups related to the notifications
|
/// Get the ID of all the groups related to the notifications
|
||||||
/// included in the list
|
/// included in the list
|
||||||
Set<int> get groupsIds {
|
Set<int?> get groupsIds {
|
||||||
final list = Set<int>();
|
final list = Set<int?>();
|
||||||
|
|
||||||
forEach((n) {
|
forEach((n) {
|
||||||
if (n.onElemType == NotificationElementType.GROUP_PAGE)
|
if (n.onElemType == NotificationElementType.GROUP_PAGE)
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'dart:collection';
|
import 'package:comunic/lists/abstract_list.dart';
|
||||||
|
|
||||||
import 'package:comunic/models/post.dart';
|
import 'package:comunic/models/post.dart';
|
||||||
|
|
||||||
/// Posts List
|
/// Posts List
|
||||||
@ -8,37 +7,25 @@ import 'package:comunic/models/post.dart';
|
|||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class PostsList extends ListBase<Post> {
|
class PostsList extends AbstractList<Post> {
|
||||||
List<Post> _list = [];
|
|
||||||
|
|
||||||
int get length => _list.length;
|
|
||||||
|
|
||||||
set length(int l) => _list.length = l;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Post operator [](int index) => _list[index];
|
|
||||||
|
|
||||||
@override
|
|
||||||
void operator []=(int index, Post value) => _list[index] = value;
|
|
||||||
|
|
||||||
// Get the list of users ID in this set
|
// Get the list of users ID in this set
|
||||||
Set<int> get usersID {
|
Set<int?> get usersID {
|
||||||
Set<int> set = Set();
|
Set<int?> set = Set();
|
||||||
|
|
||||||
forEach((p) {
|
forEach((p) {
|
||||||
set.add(p.userID);
|
set.add(p.userID);
|
||||||
|
|
||||||
if (p.userPageID != null && p.userPageID > 0) set.add(p.userPageID);
|
if (p.userPageID != null && p.userPageID! > 0) set.add(p.userPageID);
|
||||||
|
|
||||||
if (p.comments != null) set.addAll(p.comments.usersID);
|
if (p.comments != null) set.addAll(p.comments!.usersID);
|
||||||
});
|
});
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the list of groups in this list of posts
|
/// Get the list of groups in this list of posts
|
||||||
Set<int> get groupsID {
|
Set<int?> get groupsID {
|
||||||
Set<int> set = Set();
|
Set<int?> set = Set();
|
||||||
|
|
||||||
forEach((p) {
|
forEach((p) {
|
||||||
if (p.isGroupPost) set.add(p.groupID);
|
if (p.isGroupPost) set.add(p.groupID);
|
||||||
@ -49,8 +36,7 @@ class PostsList extends ListBase<Post> {
|
|||||||
|
|
||||||
/// Get the ID of the oldest post of this list. Returns 0 if the list is empty
|
/// Get the ID of the oldest post of this list. Returns 0 if the list is empty
|
||||||
int get oldestID {
|
int get oldestID {
|
||||||
if(isEmpty)
|
if (isEmpty) return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
return this.elementAt(length - 1).id;
|
return this.elementAt(length - 1).id;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ import 'package:comunic/models/unread_conversation.dart';
|
|||||||
|
|
||||||
class UnreadConversationsList extends AbstractList<UnreadConversation> {
|
class UnreadConversationsList extends AbstractList<UnreadConversation> {
|
||||||
/// Get the ID of the users included in this list
|
/// Get the ID of the users included in this list
|
||||||
Set<int> get usersID {
|
Set<int?> get usersID {
|
||||||
final set = Set<int>();
|
final set = Set<int?>();
|
||||||
forEach((element) {
|
forEach((element) {
|
||||||
set.addAll(element.conv.membersID);
|
set.addAll(element.conv.membersID);
|
||||||
set.addAll(element.message.usersID);
|
set.addAll(element.message.usersID);
|
||||||
@ -17,8 +17,8 @@ class UnreadConversationsList extends AbstractList<UnreadConversation> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the ID of the groups references ind this list
|
/// Get the ID of the groups references ind this list
|
||||||
Set<int> get groupsID {
|
Set<int?> get groupsID {
|
||||||
final set = Set<int>();
|
final set = Set<int?>();
|
||||||
forEach((element) {
|
forEach((element) {
|
||||||
if (element.conv.isGroupConversation) set.add(element.conv.groupID);
|
if (element.conv.isGroupConversation) set.add(element.conv.groupID);
|
||||||
});
|
});
|
||||||
|
@ -24,7 +24,7 @@ class UsersList extends ListBase<User> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Find a user with a specific ID
|
/// Find a user with a specific ID
|
||||||
User getUser(int userID) {
|
User getUser(int? userID) {
|
||||||
for (int i = 0; i < this.length; i++)
|
for (int i = 0; i < this.length; i++)
|
||||||
if (this[i].id == userID) return this[i];
|
if (this[i].id == userID) return this[i];
|
||||||
|
|
||||||
@ -32,8 +32,11 @@ class UsersList extends ListBase<User> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Check if the user is included in this list or not
|
/// Check if the user is included in this list or not
|
||||||
bool hasUser(int userID) => any((f) => f.id == userID);
|
bool hasUser(int? userID) => any((f) => f.id == userID);
|
||||||
|
|
||||||
/// Get the list of users ID present in this list
|
/// Get the list of users ID present in this list
|
||||||
List<int> get usersID => List.generate(length, (i) => this[i].id);
|
List<int?> get usersID => List.generate(length, (i) => this[i].id);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void add(User element) => _list.add(element);
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,9 @@ import 'package:comunic/models/config.dart';
|
|||||||
import 'package:comunic/ui/widgets/init_widget.dart';
|
import 'package:comunic/ui/widgets/init_widget.dart';
|
||||||
import 'package:comunic/utils/flutter_utils.dart';
|
import 'package:comunic/utils/flutter_utils.dart';
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:connectivity/connectivity.dart';
|
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
/// Main file of the application
|
/// Main file of the application
|
||||||
///
|
///
|
||||||
@ -43,10 +44,9 @@ class ComunicApplication extends StatefulWidget {
|
|||||||
final PreferencesHelper preferences;
|
final PreferencesHelper preferences;
|
||||||
|
|
||||||
const ComunicApplication({
|
const ComunicApplication({
|
||||||
Key key,
|
Key? key,
|
||||||
@required this.preferences,
|
required this.preferences,
|
||||||
}) : assert(preferences != null),
|
}) : super(key: key);
|
||||||
super(key: key);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ComunicApplicationState createState() => ComunicApplicationState();
|
ComunicApplicationState createState() => ComunicApplicationState();
|
||||||
@ -68,7 +68,8 @@ class ComunicApplicationState extends State<ComunicApplication> {
|
|||||||
primaryColor: config().primaryColor,
|
primaryColor: config().primaryColor,
|
||||||
primaryColorDark: config().primaryColorDark,
|
primaryColorDark: config().primaryColorDark,
|
||||||
appBarTheme: AppBarTheme(
|
appBarTheme: AppBarTheme(
|
||||||
brightness: Brightness.dark,
|
backgroundColor: config().primaryColor,
|
||||||
|
systemOverlayStyle: SystemUiOverlayStyle.light,
|
||||||
)),
|
)),
|
||||||
showPerformanceOverlay: prefs.showPerformancesOverlay,
|
showPerformanceOverlay: prefs.showPerformancesOverlay,
|
||||||
);
|
);
|
||||||
|
@ -11,7 +11,7 @@ import 'package:comunic/utils/flutter_utils.dart';
|
|||||||
/// Fix HTTPS issue
|
/// Fix HTTPS issue
|
||||||
class MyHttpOverride extends HttpOverrides {
|
class MyHttpOverride extends HttpOverrides {
|
||||||
@override
|
@override
|
||||||
HttpClient createHttpClient(SecurityContext context) {
|
HttpClient createHttpClient(SecurityContext? context) {
|
||||||
return super.createHttpClient(context)
|
return super.createHttpClient(context)
|
||||||
..badCertificateCallback = (cert, host, port) {
|
..badCertificateCallback = (cert, host, port) {
|
||||||
return host == "devweb.local"; // Forcefully trust local website
|
return host == "devweb.local"; // Forcefully trust local website
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
/// Account image settings
|
/// Account image settings
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
@ -12,10 +10,8 @@ class AccountImageSettings {
|
|||||||
final AccountImageVisibilityLevels visibility;
|
final AccountImageVisibilityLevels visibility;
|
||||||
|
|
||||||
const AccountImageSettings({
|
const AccountImageSettings({
|
||||||
@required this.hasImage,
|
required this.hasImage,
|
||||||
@required this.imageURL,
|
required this.imageURL,
|
||||||
@required this.visibility,
|
required this.visibility,
|
||||||
}) : assert(hasImage != null),
|
});
|
||||||
assert(imageURL != null),
|
|
||||||
assert(visibility != null);
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import 'package:comunic/enums/likes_type.dart';
|
import 'package:comunic/enums/likes_type.dart';
|
||||||
import 'package:comunic/models/conversation.dart';
|
import 'package:comunic/models/conversation.dart';
|
||||||
import 'package:comunic/models/like_element.dart';
|
import 'package:comunic/models/like_element.dart';
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'group.dart';
|
import 'group.dart';
|
||||||
|
|
||||||
@ -10,36 +9,35 @@ import 'group.dart';
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class AdvancedGroupInfo extends Group implements LikeElement {
|
class AdvancedGroupInfo extends Group implements LikeElement {
|
||||||
bool isMembersListPublic;
|
bool? isMembersListPublic;
|
||||||
final int timeCreate;
|
final int? timeCreate;
|
||||||
String description;
|
String description;
|
||||||
String url;
|
String url;
|
||||||
int likes;
|
int likes;
|
||||||
bool userLike;
|
bool userLike;
|
||||||
List<Conversation> conversations;
|
List<Conversation>? conversations;
|
||||||
bool isForezGroup;
|
bool isForezGroup;
|
||||||
|
|
||||||
AdvancedGroupInfo({
|
AdvancedGroupInfo({
|
||||||
@required int id,
|
required int id,
|
||||||
@required String name,
|
required String name,
|
||||||
@required String iconURL,
|
required String iconURL,
|
||||||
@required int numberMembers,
|
required int numberMembers,
|
||||||
@required GroupMembershipLevel membershipLevel,
|
required GroupMembershipLevel membershipLevel,
|
||||||
@required GroupVisibilityLevel visibilityLevel,
|
required GroupVisibilityLevel visibilityLevel,
|
||||||
@required GroupRegistrationLevel registrationLevel,
|
required GroupRegistrationLevel registrationLevel,
|
||||||
@required GroupPostCreationLevel postCreationLevel,
|
required GroupPostCreationLevel postCreationLevel,
|
||||||
@required String virtualDirectory,
|
required String virtualDirectory,
|
||||||
@required bool following,
|
required bool following,
|
||||||
@required this.isMembersListPublic,
|
required this.isMembersListPublic,
|
||||||
@required this.timeCreate,
|
required this.timeCreate,
|
||||||
@required this.description,
|
required this.description,
|
||||||
@required this.url,
|
required this.url,
|
||||||
@required this.likes,
|
required this.likes,
|
||||||
@required this.userLike,
|
required this.userLike,
|
||||||
@required this.conversations,
|
required this.conversations,
|
||||||
@required this.isForezGroup,
|
required this.isForezGroup,
|
||||||
}) : assert(isForezGroup != null),
|
}) : super(
|
||||||
super(
|
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
iconURL: iconURL,
|
iconURL: iconURL,
|
||||||
@ -54,8 +52,7 @@ class AdvancedGroupInfo extends Group implements LikeElement {
|
|||||||
@override
|
@override
|
||||||
LikesType likeType = LikesType.GROUP;
|
LikesType likeType = LikesType.GROUP;
|
||||||
|
|
||||||
get hasURL => url != null && url.isNotEmpty && url != "null";
|
get hasURL => url.isNotEmpty && url != "null";
|
||||||
|
|
||||||
get hasDescription =>
|
get hasDescription => description.isNotEmpty && description != "null";
|
||||||
description != null && description.isNotEmpty && description != "null";
|
|
||||||
}
|
}
|
||||||
|
@ -3,51 +3,42 @@ import 'package:comunic/enums/user_page_visibility.dart';
|
|||||||
import 'package:comunic/lists/custom_emojies_list.dart';
|
import 'package:comunic/lists/custom_emojies_list.dart';
|
||||||
import 'package:comunic/models/like_element.dart';
|
import 'package:comunic/models/like_element.dart';
|
||||||
import 'package:comunic/models/user.dart';
|
import 'package:comunic/models/user.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Advanced user information
|
/// Advanced user information
|
||||||
///
|
///
|
||||||
/// @author Pierre HUBERT
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
class AdvancedUserInfo extends User implements LikeElement {
|
class AdvancedUserInfo extends User implements LikeElement {
|
||||||
final String emailAddress;
|
final String? emailAddress;
|
||||||
final String publicNote;
|
final String publicNote;
|
||||||
final bool canPostTexts;
|
final bool canPostTexts;
|
||||||
final bool isFriendsListPublic;
|
final bool isFriendsListPublic;
|
||||||
final int numberFriends;
|
final int numberFriends;
|
||||||
final int accountCreationTime;
|
final int accountCreationTime;
|
||||||
final String personalWebsite;
|
final String personalWebsite;
|
||||||
final String location;
|
final String? location;
|
||||||
bool userLike;
|
bool userLike;
|
||||||
int likes;
|
int likes;
|
||||||
|
|
||||||
AdvancedUserInfo({
|
AdvancedUserInfo({
|
||||||
@required int id,
|
required int id,
|
||||||
@required String firstName,
|
required String firstName,
|
||||||
@required String lastName,
|
required String lastName,
|
||||||
@required UserPageVisibility pageVisibility,
|
required UserPageVisibility pageVisibility,
|
||||||
@required String virtualDirectory,
|
required String? virtualDirectory,
|
||||||
@required String accountImageURL,
|
required String accountImageURL,
|
||||||
@required CustomEmojiesList customEmojies,
|
required CustomEmojiesList customEmojies,
|
||||||
@required this.emailAddress,
|
required this.emailAddress,
|
||||||
@required this.publicNote,
|
required this.publicNote,
|
||||||
@required this.canPostTexts,
|
required this.canPostTexts,
|
||||||
@required this.isFriendsListPublic,
|
required this.isFriendsListPublic,
|
||||||
@required this.numberFriends,
|
required this.numberFriends,
|
||||||
@required this.accountCreationTime,
|
required this.accountCreationTime,
|
||||||
@required this.personalWebsite,
|
required this.personalWebsite,
|
||||||
@required this.location,
|
required this.location,
|
||||||
@required this.userLike,
|
required this.userLike,
|
||||||
@required this.likes,
|
required this.likes,
|
||||||
}) : assert(publicNote != null),
|
}) : super(
|
||||||
assert(canPostTexts != null),
|
|
||||||
assert(isFriendsListPublic != null),
|
|
||||||
assert(numberFriends != null),
|
|
||||||
assert(accountCreationTime != null),
|
|
||||||
assert(personalWebsite != null),
|
|
||||||
assert(userLike != null),
|
|
||||||
assert(likes != null),
|
|
||||||
super(
|
|
||||||
id: id,
|
id: id,
|
||||||
firstName: firstName,
|
firstName: firstName,
|
||||||
lastName: lastName,
|
lastName: lastName,
|
||||||
@ -60,9 +51,9 @@ class AdvancedUserInfo extends User implements LikeElement {
|
|||||||
|
|
||||||
bool get hasPersonalWebsite => personalWebsite.isNotEmpty;
|
bool get hasPersonalWebsite => personalWebsite.isNotEmpty;
|
||||||
|
|
||||||
bool get hasEmailAddress => emailAddress != null && emailAddress.isNotEmpty;
|
bool get hasEmailAddress => emailAddress != null && emailAddress!.isNotEmpty;
|
||||||
|
|
||||||
bool get hasLocation => location != null && location.isNotEmpty;
|
bool get hasLocation => location != null && location!.isNotEmpty;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LikesType get likeType => LikesType.USER;
|
LikesType get likeType => LikesType.USER;
|
||||||
|
@ -4,7 +4,6 @@ import 'package:comunic/helpers/api_helper.dart';
|
|||||||
import 'package:comunic/models/api_response.dart';
|
import 'package:comunic/models/api_response.dart';
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
import 'package:http_parser/http_parser.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// API Request model
|
/// API Request model
|
||||||
///
|
///
|
||||||
@ -14,8 +13,8 @@ import 'package:meta/meta.dart';
|
|||||||
|
|
||||||
class BytesFile {
|
class BytesFile {
|
||||||
final String filename;
|
final String filename;
|
||||||
final List<int> bytes;
|
final List<int>? bytes;
|
||||||
final MediaType type;
|
final MediaType? type;
|
||||||
|
|
||||||
const BytesFile(
|
const BytesFile(
|
||||||
this.filename,
|
this.filename,
|
||||||
@ -27,42 +26,36 @@ class BytesFile {
|
|||||||
class APIRequest {
|
class APIRequest {
|
||||||
final String uri;
|
final String uri;
|
||||||
final bool needLogin;
|
final bool needLogin;
|
||||||
ProgressCallback progressCallback;
|
ProgressCallback? progressCallback;
|
||||||
CancelToken cancelToken;
|
CancelToken? cancelToken;
|
||||||
Map<String, String> args;
|
Map<String, String?>? args;
|
||||||
Map<String, File> files = Map();
|
Map<String, File> files = Map();
|
||||||
Map<String, BytesFile> bytesFiles = Map();
|
Map<String, BytesFile?> bytesFiles = Map();
|
||||||
|
|
||||||
APIRequest({@required this.uri, this.needLogin = false, this.args})
|
APIRequest({required this.uri, this.needLogin = false, this.args}) {
|
||||||
: assert(uri != null),
|
|
||||||
assert(needLogin != null) {
|
|
||||||
if (this.args == null) this.args = Map();
|
if (this.args == null) this.args = Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest.withLogin(this.uri, {this.args})
|
APIRequest.withLogin(this.uri, {this.args}) : needLogin = true {
|
||||||
: needLogin = true,
|
|
||||||
assert(uri != null) {
|
|
||||||
if (args == null) this.args = Map();
|
if (args == null) this.args = Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest.withoutLogin(this.uri, {this.args})
|
APIRequest.withoutLogin(this.uri, {this.args}) : needLogin = false {
|
||||||
: needLogin = false,
|
|
||||||
assert(uri != null) {
|
|
||||||
if (args == null) this.args = Map();
|
if (args == null) this.args = Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest addString(String name, String value) {
|
APIRequest addString(String name, String? value) {
|
||||||
args[name] = value;
|
args![name] = value;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest addInt(String name, int value) {
|
APIRequest addInt(String name, int? value) {
|
||||||
args[name] = value.toString();
|
args![name] = value.toString();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest addBool(String name, bool value) {
|
APIRequest addBool(String name, bool value) {
|
||||||
args[name] = value ? "true" : "false";
|
args![name] = value ? "true" : "false";
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,12 +64,12 @@ class APIRequest {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
APIRequest addBytesFile(String name, BytesFile file) {
|
APIRequest addBytesFile(String name, BytesFile? file) {
|
||||||
this.bytesFiles[name] = file;
|
this.bytesFiles[name] = file;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addArgs(Map<String, String> newArgs) => args.addAll(newArgs);
|
void addArgs(Map<String, String> newArgs) => args!.addAll(newArgs);
|
||||||
|
|
||||||
/// Execute the request
|
/// Execute the request
|
||||||
Future<APIResponse> exec() async => APIHelper().exec(this);
|
Future<APIResponse> exec() async => APIHelper().exec(this);
|
||||||
|
@ -6,13 +6,13 @@ import 'dart:convert';
|
|||||||
|
|
||||||
class APIResponse {
|
class APIResponse {
|
||||||
final int code;
|
final int code;
|
||||||
final String content;
|
final String? content;
|
||||||
|
|
||||||
const APIResponse(this.code, this.content) : assert(code != null);
|
const APIResponse(this.code, this.content);
|
||||||
|
|
||||||
List<dynamic> getArray() => jsonDecode(this.content);
|
List<dynamic>? getArray() => jsonDecode(this.content!);
|
||||||
|
|
||||||
Map<String, dynamic> getObject() => jsonDecode(this.content);
|
Map<String, dynamic> getObject() => jsonDecode(this.content!);
|
||||||
|
|
||||||
/// Check if the request is successful or not
|
/// Check if the request is successful or not
|
||||||
bool get isOK => code == 200;
|
bool get isOK => code == 200;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
|
|
||||||
/// Application settings
|
/// Application settings
|
||||||
///
|
///
|
||||||
@ -10,10 +10,8 @@ class ApplicationPreferences {
|
|||||||
bool showPerformancesOverlay;
|
bool showPerformancesOverlay;
|
||||||
|
|
||||||
ApplicationPreferences({
|
ApplicationPreferences({
|
||||||
@required this.enableDarkMode,
|
required this.enableDarkMode,
|
||||||
@required this.forceMobileMode,
|
required this.forceMobileMode,
|
||||||
@required this.showPerformancesOverlay,
|
required this.showPerformancesOverlay,
|
||||||
}) : assert(enableDarkMode != null),
|
}) ;
|
||||||
assert(forceMobileMode != null),
|
|
||||||
assert(showPerformancesOverlay != null);
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Authentication details
|
/// Authentication details
|
||||||
///
|
///
|
||||||
@ -8,7 +8,5 @@ class AuthenticationDetails {
|
|||||||
final String email;
|
final String email;
|
||||||
final String password;
|
final String password;
|
||||||
|
|
||||||
const AuthenticationDetails({@required this.email, @required this.password})
|
const AuthenticationDetails({required this.email, required this.password});
|
||||||
: assert(email != null),
|
|
||||||
assert(password != null);
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import 'package:comunic/helpers/database/database_contract.dart';
|
import 'package:comunic/helpers/database/database_contract.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Cache base model
|
/// Cache base model
|
||||||
///
|
///
|
||||||
@ -8,7 +7,7 @@ import 'package:meta/meta.dart';
|
|||||||
abstract class CacheModel {
|
abstract class CacheModel {
|
||||||
final int id;
|
final int id;
|
||||||
|
|
||||||
const CacheModel({@required this.id}) : assert(id != null);
|
const CacheModel({required this.id});
|
||||||
|
|
||||||
/// Initialize a CacheModel from a map
|
/// Initialize a CacheModel from a map
|
||||||
CacheModel.fromMap(Map<String, dynamic> map)
|
CacheModel.fromMap(Map<String, dynamic> map)
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
/// Call configuration
|
/// Call configuration
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
@ -8,8 +6,8 @@ class CallConfig {
|
|||||||
final List<String> iceServers;
|
final List<String> iceServers;
|
||||||
|
|
||||||
const CallConfig({
|
const CallConfig({
|
||||||
@required this.iceServers,
|
required this.iceServers,
|
||||||
}) : assert(iceServers != null);
|
});
|
||||||
|
|
||||||
/// Turn this call configuration into the right for the WebRTC plugin
|
/// Turn this call configuration into the right for the WebRTC plugin
|
||||||
Map<String, dynamic> get pluginConfig => {
|
Map<String, dynamic> get pluginConfig => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
import 'package:flutter_webrtc/flutter_webrtc.dart';
|
||||||
|
|
||||||
/// Single call member information
|
/// Single call member information
|
||||||
@ -10,14 +9,13 @@ enum MemberStatus { JOINED, READY }
|
|||||||
class CallMember {
|
class CallMember {
|
||||||
final int userID;
|
final int userID;
|
||||||
MemberStatus status;
|
MemberStatus status;
|
||||||
MediaStream stream;
|
MediaStream? stream;
|
||||||
|
|
||||||
CallMember({
|
CallMember({
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
this.status = MemberStatus.JOINED,
|
this.status = MemberStatus.JOINED,
|
||||||
}) : assert(userID != null),
|
});
|
||||||
assert(status != null);
|
|
||||||
|
|
||||||
bool get hasVideoStream =>
|
bool get hasVideoStream =>
|
||||||
stream != null && stream.getVideoTracks().length > 0;
|
stream != null && stream!.getVideoTracks().length > 0;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import 'package:comunic/enums/likes_type.dart';
|
|||||||
import 'package:comunic/models/displayed_content.dart';
|
import 'package:comunic/models/displayed_content.dart';
|
||||||
import 'package:comunic/models/like_element.dart';
|
import 'package:comunic/models/like_element.dart';
|
||||||
import 'package:comunic/utils/account_utils.dart' as account;
|
import 'package:comunic/utils/account_utils.dart' as account;
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Comments
|
/// Comments
|
||||||
///
|
///
|
||||||
@ -16,29 +15,22 @@ class Comment implements LikeElement {
|
|||||||
final int postID;
|
final int postID;
|
||||||
final int timeSent;
|
final int timeSent;
|
||||||
DisplayedString content;
|
DisplayedString content;
|
||||||
final String imageURL;
|
final String? imageURL;
|
||||||
int likes;
|
int likes;
|
||||||
bool userLike;
|
bool userLike;
|
||||||
|
|
||||||
Comment({
|
Comment({
|
||||||
@required this.id,
|
required this.id,
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
@required this.postID,
|
required this.postID,
|
||||||
@required this.timeSent,
|
required this.timeSent,
|
||||||
@required this.content,
|
required this.content,
|
||||||
@required this.imageURL,
|
required this.imageURL,
|
||||||
@required this.likes,
|
required this.likes,
|
||||||
@required this.userLike,
|
required this.userLike,
|
||||||
}) : assert(id != null),
|
});
|
||||||
assert(userID != null),
|
|
||||||
assert(postID != null),
|
|
||||||
assert(timeSent != null),
|
|
||||||
assert(content != null),
|
|
||||||
assert(likes != null),
|
|
||||||
assert(userLike != null);
|
|
||||||
|
|
||||||
bool get hasContent =>
|
bool get hasContent => !content.isNull && content.length > 0;
|
||||||
content != null && !content.isNull && content.length > 0;
|
|
||||||
|
|
||||||
bool get hasImage => imageURL != null;
|
bool get hasImage => imageURL != null;
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
import 'package:comunic/ui/routes/tour_route.dart';
|
import 'package:comunic/ui/routes/tour_route.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Application configuration model
|
/// Application configuration model
|
||||||
///
|
///
|
||||||
@ -19,27 +16,27 @@ class Config {
|
|||||||
|
|
||||||
// Theme customization
|
// Theme customization
|
||||||
final Color splashBackgroundColor;
|
final Color splashBackgroundColor;
|
||||||
final Color primaryColor;
|
final Color? primaryColor;
|
||||||
final Color primaryColorDark;
|
final Color? primaryColorDark;
|
||||||
final String appName;
|
final String appName;
|
||||||
final String appQuickDescription;
|
final String? appQuickDescription;
|
||||||
final Color unreadConversationColor;
|
final Color? unreadConversationColor;
|
||||||
final Color defaultConversationColor;
|
final Color? defaultConversationColor;
|
||||||
|
|
||||||
// Entries for the welcome tour
|
// Entries for the welcome tour
|
||||||
final TourEntriesBuilder toursEntriesBuilder;
|
final TourEntriesBuilder? toursEntriesBuilder;
|
||||||
|
|
||||||
// Custom initialization
|
// Custom initialization
|
||||||
final Future<void> Function() additionalLoading;
|
final Future<void> Function()? additionalLoading;
|
||||||
|
|
||||||
// Custom main application route
|
// Custom main application route
|
||||||
final Widget Function(BuildContext, GlobalKey) mainRouteBuilder;
|
final Widget Function(BuildContext, GlobalKey)? mainRouteBuilder;
|
||||||
|
|
||||||
const Config({
|
const Config({
|
||||||
@required this.apiServerName,
|
required this.apiServerName,
|
||||||
@required this.apiServerUri,
|
required this.apiServerUri,
|
||||||
@required this.apiServerSecure,
|
required this.apiServerSecure,
|
||||||
@required this.clientName,
|
required this.clientName,
|
||||||
this.splashBackgroundColor = defaultColor,
|
this.splashBackgroundColor = defaultColor,
|
||||||
this.primaryColor,
|
this.primaryColor,
|
||||||
this.primaryColorDark,
|
this.primaryColorDark,
|
||||||
@ -50,17 +47,12 @@ class Config {
|
|||||||
this.toursEntriesBuilder,
|
this.toursEntriesBuilder,
|
||||||
this.additionalLoading,
|
this.additionalLoading,
|
||||||
this.mainRouteBuilder,
|
this.mainRouteBuilder,
|
||||||
}) : assert(apiServerName != null),
|
});
|
||||||
assert(apiServerUri != null),
|
|
||||||
assert(apiServerSecure != null),
|
|
||||||
assert(clientName != null),
|
|
||||||
assert(splashBackgroundColor != null),
|
|
||||||
assert(appName != null);
|
|
||||||
|
|
||||||
/// Get and set static configuration
|
/// Get and set static configuration
|
||||||
static Config _config;
|
static Config? _config;
|
||||||
|
|
||||||
static Config get() {
|
static Config? get() {
|
||||||
return _config;
|
return _config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,5 +63,5 @@ class Config {
|
|||||||
|
|
||||||
/// Get the current configuration of the application
|
/// Get the current configuration of the application
|
||||||
Config config() {
|
Config config() {
|
||||||
return Config.get();
|
return Config.get()!;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
|
import 'package:collection/collection.dart' show IterableExtension;
|
||||||
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
|
import 'package:comunic/helpers/serialization/base_serialization_helper.dart';
|
||||||
import 'package:comunic/models/conversation_member.dart';
|
import 'package:comunic/models/conversation_member.dart';
|
||||||
import 'package:comunic/utils/account_utils.dart';
|
import 'package:comunic/utils/account_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
import 'group.dart';
|
import 'group.dart';
|
||||||
|
|
||||||
@ -13,44 +13,38 @@ import 'group.dart';
|
|||||||
enum CallCapabilities { NONE, AUDIO, VIDEO }
|
enum CallCapabilities { NONE, AUDIO, VIDEO }
|
||||||
|
|
||||||
class Conversation extends SerializableElement<Conversation> {
|
class Conversation extends SerializableElement<Conversation> {
|
||||||
final int id;
|
final int? id;
|
||||||
final int lastActivity;
|
final int? lastActivity;
|
||||||
final String name;
|
final String? name;
|
||||||
final Color color;
|
final Color? color;
|
||||||
final String logoURL;
|
final String? logoURL;
|
||||||
final int groupID;
|
final int? groupID;
|
||||||
final GroupMembershipLevel groupMinMembershipLevel;
|
final GroupMembershipLevel? groupMinMembershipLevel;
|
||||||
final List<ConversationMember> members;
|
final List<ConversationMember>? members;
|
||||||
final bool canEveryoneAddMembers;
|
final bool? canEveryoneAddMembers;
|
||||||
final CallCapabilities callCapabilities;
|
final CallCapabilities callCapabilities;
|
||||||
final bool isHavingCall;
|
final bool isHavingCall;
|
||||||
|
|
||||||
Conversation({
|
Conversation({
|
||||||
@required this.id,
|
/*required*/ required int this.id,
|
||||||
@required this.lastActivity,
|
/*required*/ required int this.lastActivity,
|
||||||
@required this.name,
|
required this.name,
|
||||||
@required this.color,
|
required this.color,
|
||||||
@required this.logoURL,
|
required this.logoURL,
|
||||||
@required this.groupID,
|
required this.groupID,
|
||||||
@required this.groupMinMembershipLevel,
|
required this.groupMinMembershipLevel,
|
||||||
@required this.members,
|
/*required*/ required List<ConversationMember> this.members,
|
||||||
@required this.canEveryoneAddMembers,
|
/*required*/ required bool this.canEveryoneAddMembers,
|
||||||
this.callCapabilities = CallCapabilities.NONE,
|
this.callCapabilities = CallCapabilities.NONE,
|
||||||
this.isHavingCall = false,
|
this.isHavingCall = false,
|
||||||
}) : assert(id != null),
|
}) : assert((groupID == null) == (groupMinMembershipLevel == null));
|
||||||
assert(lastActivity != null),
|
|
||||||
assert(members != null),
|
|
||||||
assert(canEveryoneAddMembers != null),
|
|
||||||
assert((groupID == null) == (groupMinMembershipLevel == null)),
|
|
||||||
assert(callCapabilities != null),
|
|
||||||
assert(isHavingCall != null);
|
|
||||||
|
|
||||||
/// Check out whether a conversation has a fixed name or not
|
/// Check out whether a conversation has a fixed name or not
|
||||||
bool get hasName => this.name != null;
|
bool get hasName => this.name != null;
|
||||||
|
|
||||||
/// Get current user membership
|
/// Get current user membership
|
||||||
ConversationMember get membership =>
|
ConversationMember get membership =>
|
||||||
members.firstWhere((m) => m.userID == userID());
|
members!.firstWhere((m) => m.userID == userID());
|
||||||
|
|
||||||
/// Check out whether current user of the application is an admin
|
/// Check out whether current user of the application is an admin
|
||||||
bool get isAdmin => membership.isAdmin;
|
bool get isAdmin => membership.isAdmin;
|
||||||
@ -62,17 +56,17 @@ class Conversation extends SerializableElement<Conversation> {
|
|||||||
bool get following => membership.following;
|
bool get following => membership.following;
|
||||||
|
|
||||||
/// Get the list of members in the conversation
|
/// Get the list of members in the conversation
|
||||||
Set<int> get membersID => members.map((e) => e.userID).toSet();
|
Set<int?> get membersID => members!.map((e) => e.userID).toSet();
|
||||||
|
|
||||||
/// Get the list of admins in the conversation
|
/// Get the list of admins in the conversation
|
||||||
Set<int> get adminsID =>
|
Set<int?> get adminsID =>
|
||||||
members.where((e) => e.isAdmin).map((e) => e.userID).toSet();
|
members!.where((e) => e.isAdmin).map((e) => e.userID).toSet();
|
||||||
|
|
||||||
/// Get the list of the OTHER members of the conversation (all except current user)
|
/// Get the list of the OTHER members of the conversation (all except current user)
|
||||||
Set<int> get otherMembersID => membersID..remove(userID());
|
Set<int?> get otherMembersID => membersID..remove(userID());
|
||||||
|
|
||||||
/// Check if the last message has been seen or not
|
/// Check if the last message has been seen or not
|
||||||
bool get sawLastMessage => lastActivity <= membership.lastAccessTime;
|
bool get sawLastMessage => lastActivity! <= membership.lastAccessTime;
|
||||||
|
|
||||||
/// Check out whether a conversation is managed or not
|
/// Check out whether a conversation is managed or not
|
||||||
bool get isManaged => isGroupConversation;
|
bool get isManaged => isGroupConversation;
|
||||||
@ -87,9 +81,8 @@ class Conversation extends SerializableElement<Conversation> {
|
|||||||
color = map["color"] == null ? null : Color(map["color"]),
|
color = map["color"] == null ? null : Color(map["color"]),
|
||||||
logoURL = map["logoURL"],
|
logoURL = map["logoURL"],
|
||||||
groupID = map["groupID"],
|
groupID = map["groupID"],
|
||||||
groupMinMembershipLevel = GroupMembershipLevel.values.firstWhere(
|
groupMinMembershipLevel = GroupMembershipLevel.values.firstWhereOrNull(
|
||||||
(element) => element.toString() == map["groupMinMembershipLevel"],
|
(element) => element.toString() == map["groupMinMembershipLevel"]),
|
||||||
orElse: () => null),
|
|
||||||
lastActivity = map["lastActivity"],
|
lastActivity = map["lastActivity"],
|
||||||
members = map["members"]
|
members = map["members"]
|
||||||
.map((el) => ConversationMember.fromJSON(el))
|
.map((el) => ConversationMember.fromJSON(el))
|
||||||
@ -110,13 +103,13 @@ class Conversation extends SerializableElement<Conversation> {
|
|||||||
"groupID": groupID,
|
"groupID": groupID,
|
||||||
"groupMinMembershipLevel": groupMinMembershipLevel?.toString(),
|
"groupMinMembershipLevel": groupMinMembershipLevel?.toString(),
|
||||||
"lastActivity": lastActivity,
|
"lastActivity": lastActivity,
|
||||||
"members": members.map((e) => e.toJson()).toList(),
|
"members": members!.map((e) => e.toJson()).toList(),
|
||||||
"canEveryoneAddMembers": canEveryoneAddMembers,
|
"canEveryoneAddMembers": canEveryoneAddMembers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int compareTo(Conversation other) {
|
int compareTo(Conversation other) {
|
||||||
return other.lastActivity.compareTo(this.lastActivity);
|
return other.lastActivity!.compareTo(this.lastActivity!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
|
||||||
|
|
||||||
/// Conversation member
|
/// Conversation member
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
@ -12,16 +10,12 @@ class ConversationMember {
|
|||||||
final bool isAdmin;
|
final bool isAdmin;
|
||||||
|
|
||||||
const ConversationMember({
|
const ConversationMember({
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
@required this.lastMessageSeen,
|
required this.lastMessageSeen,
|
||||||
@required this.lastAccessTime,
|
required this.lastAccessTime,
|
||||||
@required this.following,
|
required this.following,
|
||||||
@required this.isAdmin,
|
required this.isAdmin,
|
||||||
}) : assert(userID != null),
|
});
|
||||||
assert(lastMessageSeen != null),
|
|
||||||
assert(lastAccessTime != null),
|
|
||||||
assert(following != null),
|
|
||||||
assert(isAdmin != null);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
'userID': userID,
|
'userID': userID,
|
||||||
|
@ -4,7 +4,6 @@ import 'package:comunic/models/displayed_content.dart';
|
|||||||
import 'package:comunic/utils/account_utils.dart' as account;
|
import 'package:comunic/utils/account_utils.dart' as account;
|
||||||
import 'package:comunic/utils/intl_utils.dart';
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
|
|
||||||
/// Single conversation message
|
/// Single conversation message
|
||||||
///
|
///
|
||||||
@ -31,27 +30,24 @@ const _ConversationFileMimeTypeMapping = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ConversationMessageFile {
|
class ConversationMessageFile {
|
||||||
final String url;
|
final String? url;
|
||||||
final int size;
|
final int? size;
|
||||||
final String name;
|
final String? name;
|
||||||
final String thumbnail;
|
final String? thumbnail;
|
||||||
final String type;
|
final String? type;
|
||||||
|
|
||||||
const ConversationMessageFile({
|
const ConversationMessageFile({
|
||||||
@required this.url,
|
required String this.url,
|
||||||
@required this.size,
|
required int this.size,
|
||||||
@required this.name,
|
required String this.name,
|
||||||
@required this.thumbnail,
|
required this.thumbnail,
|
||||||
@required this.type,
|
required String this.type,
|
||||||
}) : assert(url != null),
|
});
|
||||||
assert(size != null),
|
|
||||||
assert(name != null),
|
|
||||||
assert(type != null);
|
|
||||||
|
|
||||||
/// Get the type of file
|
/// Get the type of file
|
||||||
ConversationMessageFileType get fileType {
|
ConversationMessageFileType? get fileType {
|
||||||
if (type != null && _ConversationFileMimeTypeMapping.containsKey(type))
|
if (type != null && _ConversationFileMimeTypeMapping.containsKey(type))
|
||||||
return _ConversationFileMimeTypeMapping[type];
|
return _ConversationFileMimeTypeMapping[type!];
|
||||||
else
|
else
|
||||||
return ConversationMessageFileType.OTHER;
|
return ConversationMessageFileType.OTHER;
|
||||||
}
|
}
|
||||||
@ -103,21 +99,20 @@ enum ConversationServerMessageType {
|
|||||||
|
|
||||||
class ConversationServerMessage {
|
class ConversationServerMessage {
|
||||||
final ConversationServerMessageType type;
|
final ConversationServerMessageType type;
|
||||||
final int userID;
|
final int? userID;
|
||||||
final int userWhoAdded;
|
final int? userWhoAdded;
|
||||||
final int userAdded;
|
final int? userAdded;
|
||||||
final int userWhoRemoved;
|
final int? userWhoRemoved;
|
||||||
final int userRemoved;
|
final int? userRemoved;
|
||||||
|
|
||||||
const ConversationServerMessage({
|
const ConversationServerMessage({
|
||||||
@required this.type,
|
required this.type,
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
@required this.userWhoAdded,
|
required this.userWhoAdded,
|
||||||
@required this.userAdded,
|
required this.userAdded,
|
||||||
@required this.userWhoRemoved,
|
required this.userWhoRemoved,
|
||||||
@required this.userRemoved,
|
required this.userRemoved,
|
||||||
}) : assert(type != null),
|
}) : assert(userID != null ||
|
||||||
assert(userID != null ||
|
|
||||||
(type != ConversationServerMessageType.USER_CREATED_CONVERSATION &&
|
(type != ConversationServerMessageType.USER_CREATED_CONVERSATION &&
|
||||||
type != ConversationServerMessageType.USER_LEFT_CONV)),
|
type != ConversationServerMessageType.USER_LEFT_CONV)),
|
||||||
assert((userWhoAdded != null && userAdded != null) ||
|
assert((userWhoAdded != null && userAdded != null) ||
|
||||||
@ -125,47 +120,47 @@ class ConversationServerMessage {
|
|||||||
assert((userWhoRemoved != null && userRemoved != null) ||
|
assert((userWhoRemoved != null && userRemoved != null) ||
|
||||||
type != ConversationServerMessageType.USER_REMOVED_ANOTHER_USER);
|
type != ConversationServerMessageType.USER_REMOVED_ANOTHER_USER);
|
||||||
|
|
||||||
Set<int> get usersID {
|
Set<int?> get usersID {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
||||||
case ConversationServerMessageType.USER_LEFT_CONV:
|
case ConversationServerMessageType.USER_LEFT_CONV:
|
||||||
return Set()..add(userID);
|
return Set()..add(userID);
|
||||||
|
|
||||||
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
||||||
return Set()..add(userWhoAdded)..add(userAdded);
|
return Set()
|
||||||
|
..add(userWhoAdded)
|
||||||
|
..add(userAdded);
|
||||||
|
|
||||||
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
||||||
return Set()..add(userWhoRemoved)..add(userRemoved);
|
return Set()
|
||||||
|
..add(userWhoRemoved)
|
||||||
|
..add(userRemoved);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Unsupported server message type!");
|
String? getText(UsersList? list) {
|
||||||
}
|
|
||||||
|
|
||||||
String getText(UsersList list) {
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
case ConversationServerMessageType.USER_CREATED_CONVERSATION:
|
||||||
return tr("%1% created the conversation",
|
return tr("%1% created the conversation",
|
||||||
args: {"1": list.getUser(userID).fullName});
|
args: {"1": list!.getUser(userID).fullName});
|
||||||
|
|
||||||
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
case ConversationServerMessageType.USER_ADDED_ANOTHER_USER:
|
||||||
return tr("%1% added %2% to the conversation", args: {
|
return tr("%1% added %2% to the conversation", args: {
|
||||||
"1": list.getUser(userWhoAdded).fullName,
|
"1": list!.getUser(userWhoAdded).fullName,
|
||||||
"2": list.getUser(userAdded).fullName,
|
"2": list.getUser(userAdded).fullName,
|
||||||
});
|
});
|
||||||
|
|
||||||
case ConversationServerMessageType.USER_LEFT_CONV:
|
case ConversationServerMessageType.USER_LEFT_CONV:
|
||||||
return tr("%1% left the conversation", args: {
|
return tr("%1% left the conversation", args: {
|
||||||
"1": list.getUser(userID).fullName,
|
"1": list!.getUser(userID).fullName,
|
||||||
});
|
});
|
||||||
|
|
||||||
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
case ConversationServerMessageType.USER_REMOVED_ANOTHER_USER:
|
||||||
return tr("%1% removed %2% from the conversation", args: {
|
return tr("%1% removed %2% from the conversation", args: {
|
||||||
"1": list.getUser(userWhoRemoved).fullName,
|
"1": list!.getUser(userWhoRemoved).fullName,
|
||||||
"2": list.getUser(userRemoved).fullName,
|
"2": list.getUser(userRemoved).fullName,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Exception("Unsupported message type!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => {
|
Map<String, dynamic> toJson() => {
|
||||||
@ -188,29 +183,26 @@ class ConversationServerMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ConversationMessage extends SerializableElement<ConversationMessage> {
|
class ConversationMessage extends SerializableElement<ConversationMessage> {
|
||||||
final int id;
|
final int? id;
|
||||||
final int convID;
|
final int? convID;
|
||||||
final int userID;
|
final int? userID;
|
||||||
final int timeSent;
|
final int? timeSent;
|
||||||
final DisplayedString message;
|
final DisplayedString message;
|
||||||
final ConversationMessageFile file;
|
final ConversationMessageFile? file;
|
||||||
final ConversationServerMessage serverMessage;
|
final ConversationServerMessage? serverMessage;
|
||||||
|
|
||||||
ConversationMessage({
|
ConversationMessage({
|
||||||
@required this.id,
|
required int this.id,
|
||||||
@required this.convID,
|
required int this.convID,
|
||||||
@required this.userID,
|
required this.userID,
|
||||||
@required this.timeSent,
|
required int this.timeSent,
|
||||||
@required this.message,
|
required this.message,
|
||||||
@required this.file,
|
required this.file,
|
||||||
@required this.serverMessage,
|
required this.serverMessage,
|
||||||
}) : assert(id != null),
|
}) : assert(userID != null || serverMessage != null),
|
||||||
assert(convID != null),
|
assert(!message.isNull || file != null || serverMessage != null);
|
||||||
assert(userID != null || serverMessage != null),
|
|
||||||
assert(timeSent != null),
|
|
||||||
assert(message != null || file != null || serverMessage != null);
|
|
||||||
|
|
||||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timeSent * 1000);
|
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timeSent! * 1000);
|
||||||
|
|
||||||
bool get hasMessage => !message.isNull && message.length > 0;
|
bool get hasMessage => !message.isNull && message.length > 0;
|
||||||
|
|
||||||
@ -221,16 +213,16 @@ class ConversationMessage extends SerializableElement<ConversationMessage> {
|
|||||||
bool get isServerMessage => serverMessage != null;
|
bool get isServerMessage => serverMessage != null;
|
||||||
|
|
||||||
/// Get the list of the ID of the users implied in this message
|
/// Get the list of the ID of the users implied in this message
|
||||||
Set<int> get usersID {
|
Set<int?> get usersID {
|
||||||
if (userID != null) return Set()..add(userID);
|
if (userID != null) return Set()..add(userID);
|
||||||
|
|
||||||
if (serverMessage != null) return serverMessage.usersID;
|
if (serverMessage != null) return serverMessage!.usersID;
|
||||||
return Set();
|
return Set();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int compareTo(ConversationMessage other) {
|
int compareTo(ConversationMessage other) {
|
||||||
return id.compareTo(other.id);
|
return id!.compareTo(other.id!);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
|
@ -3,12 +3,11 @@
|
|||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class CountUnreadNotifications {
|
class CountUnreadNotifications {
|
||||||
int notifications;
|
int? notifications;
|
||||||
int conversations;
|
int? conversations;
|
||||||
|
|
||||||
CountUnreadNotifications({
|
CountUnreadNotifications({
|
||||||
this.notifications,
|
required int this.notifications,
|
||||||
this.conversations,
|
required int this.conversations,
|
||||||
}) : assert(notifications != null),
|
});
|
||||||
assert(conversations != null);
|
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,19 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
/// Single custom emoji information
|
/// Single custom emoji information
|
||||||
///
|
///
|
||||||
/// @author Pierre Hubert
|
/// @author Pierre Hubert
|
||||||
|
|
||||||
class CustomEmoji {
|
class CustomEmoji {
|
||||||
final int id;
|
final int? id;
|
||||||
final int userID;
|
final int? userID;
|
||||||
final String shortcut;
|
final String? shortcut;
|
||||||
final String url;
|
final String? url;
|
||||||
|
|
||||||
const CustomEmoji({
|
const CustomEmoji({
|
||||||
@required this.id,
|
required int this.id,
|
||||||
@required this.userID,
|
required int this.userID,
|
||||||
@required this.shortcut,
|
required String this.shortcut,
|
||||||
@required this.url,
|
required String this.url,
|
||||||
}) : assert(id != null),
|
});
|
||||||
assert(userID != null),
|
|
||||||
assert(shortcut != null),
|
|
||||||
assert(url != null);
|
|
||||||
|
|
||||||
Map<String, dynamic> toMap() => {
|
Map<String, dynamic> toMap() => {
|
||||||
"id": id,
|
"id": id,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user