Commit ca2395c9 authored by Erfan Jazeb Nikoo's avatar Erfan Jazeb Nikoo
Browse files

sample_data_mixpanel

- Some fixes related to the sample_data
- Added a mixpanel event
parent 1d06bf4e
Pipeline #9369 failed with stages
in 1 minute and 12 seconds
Showing with 144 additions and 118 deletions
+144 -118
......@@ -7,6 +7,7 @@ import 'package:memri/core/services/gitlab_service.dart';
import 'package:memri/core/services/graph_service.dart';
import 'package:memri/core/services/pod_service.dart';
import 'package:memri/providers/oauth_provider.dart';
import 'package:memri/providers/project_provider.dart';
class _Result {
final List<Item> items;
......@@ -29,27 +30,27 @@ class ImporterProvider with ChangeNotifier {
);
bool ableFetchImporters = true;
Map<String, Item> activePlugins = {};
Map<DataSource, Item> activePlugins = {};
Timer? refreshActiveListTimer;
Map<String, Stream<Item>?> downloadingStreams = {};
Map<String, StreamSubscription<Item>> downloadingStreamSubs = {};
Map<String, double?> progress = {};
Map<String, bool?> importerDataInPod = {};
Map<DataSource, bool?> importerDataInPod = {};
bool dataForLabelingInPod = false;
Item? selectedPlugin;
bool get isAnyImportersActive => activePlugins.values.isNotEmpty;
bool isImporterActive(String name) =>
activePlugins[name] != null ||
importerDataInPod.containsKey(name) ||
_oAuthProvider.oAuthCompletedByName(name);
bool isImporterActive(DataSource source) =>
activePlugins[source] != null ||
importerDataInPod.containsKey(source) ||
_oAuthProvider.oAuthCompletedByName(source);
bool isImporterSelected(String name) =>
isImporterActive(name) && selectedPlugin == activePlugins[name];
bool isImporterSelected(DataSource source) =>
isImporterActive(source) && selectedPlugin == activePlugins[source];
Future<void> fetchActiveImporters() async {
if (!ableFetchImporters) return;
......@@ -60,14 +61,16 @@ class ImporterProvider with ChangeNotifier {
var activeImporters = await _graphService.fetchActiveImporters();
if (activeImporters.isNotEmpty) {
activePlugins['whatsapp'] = activeImporters.firstWhere((element) =>
element.get('pluginName') == 'WhatsappPlugin' &&
element.get('status') != 'error' &&
element.get('status') != 'idle');
activePlugins['twitter'] = activeImporters.firstWhere((element) =>
element.get('pluginName') == 'TwitterPlugin' &&
element.get('status') != 'error' &&
element.get('status') != 'idle');
activePlugins[DataSource.whatsapp] = activeImporters.firstWhere(
(element) =>
element.get('pluginName') == 'WhatsappPlugin' &&
element.get('status') != 'error' &&
element.get('status') != 'idle');
activePlugins[DataSource.twitter] = activeImporters.firstWhere(
(element) =>
element.get('pluginName') == 'TwitterPlugin' &&
element.get('status') != 'error' &&
element.get('status') != 'idle');
notifyListeners();
}
}
......@@ -126,13 +129,13 @@ class ImporterProvider with ChangeNotifier {
List<Item> items = messages + tweets;
dataForLabelingInPod = items.isNotEmpty;
importerDataInPod['whatsapp'] = messages.isNotEmpty;
importerDataInPod['twitter'] = tweets.isNotEmpty;
importerDataInPod[DataSource.whatsapp] = messages.isNotEmpty;
importerDataInPod[DataSource.twitter] = tweets.isNotEmpty;
notifyListeners();
}
void importSampleData() {
if (!(importerDataInPod['sample_whatsapp'] ?? false)) {
if (!(importerDataInPod[DataSource.sampleWhatsapp] ?? false)) {
uploadSampleDataFromGitlab();
}
}
......@@ -201,7 +204,10 @@ class ImporterProvider with ChangeNotifier {
}
activePlugins = {};
importerDataInPod = {};
progress = {};
selectedPlugin = null;
ableFetchImporters = true;
dataForLabelingInPod = false;
}
refresh() {
......
......@@ -51,7 +51,7 @@ class OAuthProvider with ChangeNotifier {
late StreamSubscription<Item> gitlabOAuthStreamSubscription;
Stream<Item>? gitlabOAuthStream;
Map<String, bool> oAuthCompleted = {};
Map<DataSource, bool> oAuthCompleted = {};
String get endpoint => window.location.href.contains('localhost')
? 'http://localhost:3667'
......@@ -66,9 +66,9 @@ class OAuthProvider with ChangeNotifier {
set oauthCodeVerifier(String val) =>
_prefs.setString('oauthCodeVerifier', val);
bool oAuthCompletedByName(String name) {
bool oAuthCompletedByName(DataSource dataSource) {
if (oAuthCompleted.keys.isEmpty) return false;
return oAuthCompleted[name] ?? false;
return oAuthCompleted[dataSource] ?? false;
}
void init() {
......@@ -250,9 +250,10 @@ class OAuthProvider with ChangeNotifier {
_prefs.reload();
notifyListeners();
oAuthCompleted['twitter'] = _prefs.getBool('oauthCompleted') ?? false;
oAuthCompleted[DataSource.twitter] =
_prefs.getBool('oauthCompleted') ?? false;
if (oAuthCompleted['twitter']!) {
if (oAuthCompleted[DataSource.twitter]!) {
AppLogger.info('oauth completed');
Item item = await _podService.startImporter('TwitterPlugin',
'twitter.plugin', app.settings.twitterContainer, 'twitter');
......@@ -328,9 +329,10 @@ class OAuthProvider with ChangeNotifier {
if (status != whatsappStatus) {
AnalyticsService().logImporterStatus(status);
}
oAuthCompleted['whatsapp'] = (status == 'daemon' || status == 'done');
oAuthCompleted[DataSource.whatsapp] =
(status == 'daemon' || status == 'done');
if (!oAuthCompleted['whatsapp']!) {
if (!oAuthCompleted[DataSource.whatsapp]!) {
var url = item.get('authUrl');
if (whatsappQrUrl == null && url != null) {
whatsappQrUrl = url;
......@@ -342,7 +344,7 @@ class OAuthProvider with ChangeNotifier {
AppLogger.info(whatsappStatus);
notifyListeners();
if (oAuthCompleted['whatsapp']!) {
if (oAuthCompleted[DataSource.whatsapp]!) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerDownloading,
......
......@@ -3,6 +3,7 @@ import 'package:memri/configs/routes/route_navigator.dart';
import 'package:memri/constants/app_styles.dart';
import 'package:memri/providers/data_app_provider.dart';
import 'package:memri/providers/importer_provider.dart';
import 'package:memri/providers/project_provider.dart';
import 'package:memri/utilities/helpers/app_helper.dart';
import 'package:memri/widgets/data_app_tile.dart';
import 'package:memri/widgets/empty.dart';
......@@ -44,11 +45,11 @@ class AppsScreenState extends State<AppsScreen> {
Consumer<ImporterProvider>(
builder: (context, importerProvider, __) {
bool whatsappExist = importerProvider
.importerDataInPod['whatsapp'] ??
.importerDataInPod[DataSource.whatsapp] ??
false;
bool twitterExist = importerProvider
.importerDataInPod[DataSource.twitter] ??
false;
bool twitterExist =
importerProvider.importerDataInPod['twitter'] ??
false;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
......
......@@ -4,6 +4,7 @@ import 'package:memri/constants/app_styles.dart';
import 'package:memri/core/services/analytics_service.dart';
import 'package:memri/providers/importer_provider.dart';
import 'package:memri/providers/navigation_provider.dart';
import 'package:memri/providers/project_provider.dart';
import 'package:memri/utilities/helpers/app_helper.dart';
import 'package:memri/utilities/helpers/responsive_helper.dart';
import 'package:memri/widgets/empty.dart';
......@@ -30,12 +31,6 @@ class DataScreenState extends State<DataScreen> {
ScrollController _bodyScrollController = ScrollController();
final ScrollController _sideBarScrollController = ScrollController();
@override
void initState() {
// importerProvider.getActiveImporters();
super.initState();
}
@override
Widget build(BuildContext context) {
return WorkspaceScaffold(
......@@ -137,17 +132,19 @@ class DataScreenState extends State<DataScreen> {
children: [
ImporterTile(
title: 'WhatsApp',
status: provider.isImporterActive('whatsapp')
status: provider.isImporterActive(DataSource.whatsapp)
? 'Running'
: 'Connect',
statusColor: provider.isImporterActive('whatsapp')
? app.colors.brandGreen
: null,
active: provider.isImporterActive('whatsapp'),
selected: provider.isImporterSelected('whatsapp'),
statusColor:
provider.isImporterActive(DataSource.whatsapp)
? app.colors.brandGreen
: null,
active: provider.isImporterActive(DataSource.whatsapp),
selected:
provider.isImporterSelected(DataSource.whatsapp),
onTap: () {
AnalyticsService().logImporterSelect('whatsapp');
if (!provider.isImporterActive('whatsapp')) {
if (!provider.isImporterActive(DataSource.whatsapp)) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerConnect,
......@@ -155,22 +152,23 @@ class DataScreenState extends State<DataScreen> {
);
} else {
provider.setActivePlugin(
provider.activePlugins['whatsapp']);
provider.activePlugins[DataSource.whatsapp]);
}
},
),
ImporterTile(
title: 'Twitter',
status: provider.isImporterActive('twitter')
status: provider.isImporterActive(DataSource.twitter)
? 'Running'
: 'Connect',
statusColor: provider.isImporterActive('twitter')
statusColor: provider.isImporterActive(DataSource.twitter)
? app.colors.brandGreen
: null,
active: provider.isImporterActive('twitter'),
selected: provider.isImporterSelected('twitter'),
active: provider.isImporterActive(DataSource.twitter),
selected: provider.isImporterSelected(DataSource.twitter),
onTap: () {
if (!provider.isImporterActive('twitter')) {
AnalyticsService().logImporterSelect('twitter');
if (!provider.isImporterActive(DataSource.twitter)) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerConnect,
......@@ -178,7 +176,7 @@ class DataScreenState extends State<DataScreen> {
);
} else {
provider.setActivePlugin(
provider.activePlugins['twitter']);
provider.activePlugins[DataSource.twitter]);
}
},
),
......@@ -199,7 +197,7 @@ class DataScreenState extends State<DataScreen> {
],
),
),
if (!provider.isImporterSelected('whatsapp'))
if (!provider.isImporterSelected(DataSource.whatsapp))
Expanded(
flex: ResponsiveHelper(context).isMediumScreen ? 3 : 1,
child: Empty(),
......
......@@ -141,57 +141,71 @@ class _ProjectsCreateScreenState extends State<ProjectsCreateScreen> {
style: AppStyles.bodyText1,
),
SizedBox(height: 20),
Wrap(
spacing: 16,
runSpacing: 16,
children: [
ImporterTile(
title: 'WhatsApp',
status: 'ACTIVE',
selected: provider.dataSourceSelected ==
DataSource.whatsapp,
onTap: () => provider
.handleSelectDataSource(DataSource.whatsapp),
),
ImporterTile(
title: 'Twitter',
status: 'ACTIVE',
selected: provider.dataSourceSelected ==
DataSource.twitter,
onTap: () => provider
.handleSelectDataSource(DataSource.twitter),
),
if (widget.isSampleProject)
ImporterTile(
title: 'Sample Data',
status: 'ACTIVE',
selected: true,
onTap: () {},
),
],
),
SizedBox(height: 60),
Text('Select feature variables',
style: AppStyles.headline1),
SizedBox(height: 10),
Text(
'Feature variables represent different information available in your connected datasets. You may choose the most relevant variables based on what kind of predictions you wish your app to make. For example, if you want the app use the message body, choose ‘message text’.',
style: AppStyles.bodyText1),
SizedBox(height: 10),
Text(
'Select which information from your dataset you wish to use in your app:',
style: AppStyles.bodyText1),
SizedBox(height: 16),
Row(
children: [
for (var feature in provider
.features[provider.dataSourceSelected] ??
[])
FeatureSelectBox(provider, feature),
// FeatureSelectBox(provider, 'Date Sent'),
],
),
Consumer<ImporterProvider>(builder: (_, iProvider, __) {
return Wrap(
spacing: 16,
runSpacing: 16,
children: [
if (iProvider
.isImporterActive(DataSource.whatsapp))
ImporterTile(
title: 'WhatsApp',
status: 'Connected',
selected: provider.dataSourceSelected ==
DataSource.whatsapp,
onTap: () => provider.handleSelectDataSource(
DataSource.whatsapp),
),
if (iProvider
.isImporterActive(DataSource.twitter))
ImporterTile(
title: 'Twitter',
status: 'Connected',
selected: provider.dataSourceSelected ==
DataSource.twitter,
onTap: () => provider.handleSelectDataSource(
DataSource.twitter),
),
if (widget.isSampleProject)
ImporterTile(
title: 'Sample Data',
description:
'A static dataset of 500 messages in English',
selected: provider.dataSourceSelected ==
DataSource.sampleWhatsapp,
onTap: () => provider.handleSelectDataSource(
DataSource.sampleWhatsapp),
),
],
);
}),
SizedBox(height: 60),
if (!widget.isSampleProject)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Select feature variables',
style: AppStyles.headline1),
SizedBox(height: 10),
Text(
'Feature variables represent different information available in your connected datasets. You may choose the most relevant variables based on what kind of predictions you wish your app to make. For example, if you want the app use the message body, choose ‘message text’.',
style: AppStyles.bodyText1),
SizedBox(height: 10),
Text(
'Select which information from your dataset you wish to use in your app:',
style: AppStyles.bodyText1),
SizedBox(height: 16),
Row(
children: [
for (var feature in provider.features[
provider.dataSourceSelected] ??
[])
FeatureSelectBox(provider, feature),
],
),
SizedBox(height: 60),
],
),
Text('Add labels you want to use in your app.',
style: AppStyles.headline1),
SizedBox(height: 10),
......
import 'package:flutter/material.dart';
import 'package:memri/configs/routes/route_navigator.dart';
import 'package:memri/constants/app_styles.dart';
import 'package:memri/core/services/analytics_service.dart';
import 'package:memri/providers/importer_provider.dart';
import 'package:memri/providers/navigation_provider.dart';
import 'package:memri/providers/project_provider.dart';
......@@ -415,10 +416,13 @@ class SampleProjectButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => RouteNavigator.navigateTo(
onPressed: () {
AnalyticsService().logImporterSelect('sample_whatsapp');
RouteNavigator.navigateTo(
context: context,
route: Routes.projectsCreate,
param: {'isSample': true}),
param: {'isSample': true});
},
style: secondaryButtonStyle,
child: SizedBox(
height: 36,
......
......@@ -6,10 +6,10 @@ class ImporterTile extends StatelessWidget {
const ImporterTile({
Key? key,
required this.title,
required this.status,
required this.onTap,
this.status,
this.featureVariables,
this.storageSize,
this.description,
this.selectable = true,
this.selected = false,
this.active = false,
......@@ -18,8 +18,8 @@ class ImporterTile extends StatelessWidget {
final String title;
final int? featureVariables;
final String? storageSize;
final String status;
final String? description;
final String? status;
final VoidCallback? onTap;
final bool selectable;
final bool selected;
......@@ -74,21 +74,22 @@ class ImporterTile extends StatelessWidget {
style: AppStyles.bodyTiny
.copyWith(color: app.colors.brandGrey),
),
if (storageSize != null)
if (description != null)
Text(
storageSize!,
description!,
style: AppStyles.bodyTiny
.copyWith(color: app.colors.brandGrey),
),
Text(
status,
style: AppStyles.bodyTiny.copyWith(
fontWeight: FontWeight.w700,
color: selected
? app.colors.brandOrange
: statusColor ?? app.colors.brandOrange,
if (status != null)
Text(
status!,
style: AppStyles.bodyTiny.copyWith(
fontWeight: FontWeight.w700,
color: selected
? app.colors.brandOrange
: statusColor ?? app.colors.brandOrange,
),
),
),
],
),
),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment