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

Merge branch 'erfan/update-mixpanel' into 'dev'

erfan/update-mixpanel

See merge request !419
parents ab49aa7d 90f54fde
Pipeline #10452 passed with stages
in 6 minutes and 25 seconds
Showing with 121 additions and 71 deletions
+121 -71
......@@ -90,6 +90,25 @@ class AnalyticsService {
);
}
void logProjectOpen(String projectId) {
mixpanel!.timeEvent(AnalyticsEvents.projectOpen);
mixpanel!.track(
AnalyticsEvents.projectOpen,
properties: {_AnalyticsProperties.projectId: projectId},
);
}
void logProjectDelete(String projectId, String projectName) {
mixpanel!.timeEvent(AnalyticsEvents.projectDelete);
mixpanel!.track(
AnalyticsEvents.projectDelete,
properties: {
_AnalyticsProperties.projectId: projectId,
_AnalyticsProperties.projectName: projectName,
},
);
}
void logProjectDataSelect(var dataSources) {
mixpanel!.timeEvent(AnalyticsEvents.projectDataSelect);
mixpanel!.track(
......@@ -139,6 +158,14 @@ class AnalyticsService {
mixpanel!.track(AnalyticsEvents.projectGoogleColab);
}
void logProjectGitlabPipelineUrl(String? jobUrl) {
mixpanel!.timeEvent(AnalyticsEvents.projectGitlabPipeline);
mixpanel!.track(
AnalyticsEvents.projectGitlabPipeline,
properties: {_AnalyticsProperties.projectGitlabPipelineUrl: jobUrl},
);
}
void logProjectPluginGitlabUrl(String url) {
mixpanel!.timeEvent(AnalyticsEvents.projectPluginGitlabUrl);
mixpanel!.track(
......@@ -207,8 +234,11 @@ class AnalyticsEvents {
static const projectTrainModel = 'project_train_model';
static const projectDeployApp = 'project_deploy_app';
static const projectGoogleColab = 'project_google_colab';
static const projectGitlabPipeline = 'project_gitlab_pipeline';
static const projectTutorialLink = 'project_tutorial_link';
static const projectPluginGitlabUrl = 'project_plugin_gitlab_url';
static const projectOpen = 'project_open';
static const projectDelete = 'project_delete';
}
class _AnalyticsProperties {
......@@ -221,6 +251,7 @@ class _AnalyticsProperties {
static const importerName = 'importer_name';
static const importerStatus = 'importer_status';
static const projectId = 'project_id';
static const projectName = 'project_name';
static const projectDataSource = 'project_date_source';
static const projectDataLabels = 'project_date_labels';
......@@ -230,6 +261,7 @@ class _AnalyticsProperties {
static const projectPluginGitlabUrl = 'project_plugin_gitlab_url';
static const projectTutorialLinkLabel = 'project_tutorial_link_label';
static const projectTutorialLinkUrl = 'project_tutorial_link_url';
static const projectGitlabPipelineUrl = 'project_gitlab_pipeline_url';
static const errorName = 'error_name';
static const errorStackTrace = 'error_stack_trace';
......
......@@ -46,11 +46,12 @@ Future<void> setup() async {
locator(),
locator(),
locator(),
locator(),
));
locator.registerLazySingleton<ImporterProvider>(
() => ImporterProvider(locator(), locator(), locator(), locator()));
locator.registerLazySingleton<ImporterProvider>(() =>
ImporterProvider(locator(), locator(), locator(), locator(), locator()));
locator.registerLazySingleton<ProjectProvider>(
() => ProjectProvider(locator(), locator(), locator()));
() => ProjectProvider(locator(), locator(), locator(), locator()));
locator.registerLazySingleton<DataAppProvider>(
() => DataAppProvider(locator(), locator(), locator()));
......
......@@ -2,7 +2,9 @@ import 'dart:async';
import 'dart:convert';
import 'package:flutter/widgets.dart';
import 'package:memri/configs/routes/route_navigator.dart';
import 'package:memri/core/models/item.dart';
import 'package:memri/core/services/analytics_service.dart';
import 'package:memri/core/services/gitlab_service.dart';
import 'package:memri/core/services/graph_service.dart';
import 'package:memri/core/services/pod_service.dart';
......@@ -22,12 +24,14 @@ class ImporterProvider with ChangeNotifier {
final GraphService _graphService;
final OAuthProvider _oAuthProvider;
final GitlabService _gitlabService;
final AnalyticsService _analyticsService;
ImporterProvider(
this._podService,
this._graphService,
this._oAuthProvider,
this._gitlabService,
this._analyticsService,
);
bool ableFetchImporters = true;
......@@ -205,6 +209,30 @@ class ImporterProvider with ChangeNotifier {
return _Result(messagesList, messageEdges);
}
void onTapImporterTile(BuildContext context, DataSource dataSource) {
String sourceStr;
switch (dataSource) {
case DataSource.twitter:
sourceStr = 'twitter';
break;
case DataSource.whatsapp:
sourceStr = 'whatsapp';
break;
case DataSource.sampleWhatsapp:
sourceStr = 'sample-whatsapp';
}
_analyticsService.logImporterSelect(sourceStr);
if (!isImporterActive(dataSource)) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerConnect,
param: {'name': sourceStr},
);
} else {
setActivePlugin(activePlugins[dataSource]);
}
}
void reset() {
if (refreshActiveListTimer != null) {
refreshActiveListTimer!.cancel();
......
......@@ -25,8 +25,7 @@ class OAuthProvider with ChangeNotifier {
final OAuthService _oAuthService;
final GraphService _graphService;
final GitlabService _gitlabService;
String? gitlabOauthUrl;
final AnalyticsService _analyticsService;
OAuthProvider(
this._prefs,
......@@ -34,8 +33,10 @@ class OAuthProvider with ChangeNotifier {
this._oAuthService,
this._graphService,
this._gitlabService,
this._analyticsService,
);
String? gitlabOauthUrl;
String responseMessage = '';
String errorMessage = 'Oops, something went wrong...!\nplease try again';
String service = '';
......@@ -177,7 +178,7 @@ class OAuthProvider with ChangeNotifier {
Future<void> initGitlabOAuth() async {
setGitlabOauthUrl();
await setGitlabAccesTokenFromPod();
await setGitlabAccessTokenFromPod();
if (_gitlabService.gitlabAccessToken == null) {
// start a listener for accessToken, if it finds one, set in the gitlab api and test auth
_gitlabOAuthStream = _gitlabLatestOauthItemStream();
......@@ -196,14 +197,14 @@ class OAuthProvider with ChangeNotifier {
Stream<String> _gitlabLatestOauthItemStream() async* {
while (true) {
await Future.delayed(Duration(seconds: 1));
await setGitlabAccesTokenFromPod();
await setGitlabAccessTokenFromPod();
if (_gitlabService.gitlabAccessToken != null) {
yield _gitlabService.gitlabAccessToken!;
}
}
}
Future<void> setGitlabAccesTokenFromPod() async {
Future<void> setGitlabAccessTokenFromPod() async {
try {
_gitlabService.gitlabAccessToken ??=
await _podService.oauth2GetAccessToken('gitlab');
......@@ -352,7 +353,7 @@ class OAuthProvider with ChangeNotifier {
var status = item.get('status');
if (status != whatsappStatus) {
AnalyticsService().logImporterStatus(status);
_analyticsService.logImporterStatus(status);
}
whatsappStatus = status;
AppLogger.info(whatsappStatus);
......
// ignore_for_file: cancel_subscriptions
import 'dart:async';
import 'dart:js' as js;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
......@@ -22,8 +23,14 @@ class ProjectProvider with ChangeNotifier {
final PodService _podService;
final GraphService _graphService;
final GitlabService _gitlabService;
final AnalyticsService _analyticsService;
ProjectProvider(this._podService, this._graphService, this._gitlabService);
ProjectProvider(
this._podService,
this._graphService,
this._gitlabService,
this._analyticsService,
);
List<String> notSubmittedLabelValues = [];
......@@ -156,6 +163,7 @@ class ProjectProvider with ChangeNotifier {
RouteNavigator.navigateBack(context);
projects.removeWhere((element) => element.id == project.id);
_podService.deleteItem(project.get('id'));
_analyticsService.logProjectDelete(project.id, project.get('name'));
notifyListeners();
},
),
......@@ -187,7 +195,7 @@ class ProjectProvider with ChangeNotifier {
dataSourceSelected = dataSource;
}
if (notify) notifyListeners();
AnalyticsService().logProjectDataSelect(dataSource);
_analyticsService.logProjectDataSelect(dataSource);
}
handleCreateProject(BuildContext context, String projectName,
......@@ -215,12 +223,12 @@ class ProjectProvider with ChangeNotifier {
} else {
// TODO save everything in single bulk request
// TODO change the whatsapp to something dynamic
AnalyticsService().logProjectCreate(projectName, 'whatsapp');
_analyticsService.logProjectCreate(projectName, 'whatsapp');
await createProject(
name: projectName,
dataSource: dataSourceSelected.toString().split('.').last);
await createDataset();
AnalyticsService().logProjectAddLabels(notSubmittedLabelValues);
_analyticsService.logProjectAddLabels(notSubmittedLabelValues);
await createLabellingTask();
await createGitlabProject(repo: projectName);
notSubmittedLabelValues = [];
......@@ -518,7 +526,7 @@ class ProjectProvider with ChangeNotifier {
}
projectPackageStream = null;
projectPipelineStream = null;
AnalyticsService().logProjectTrainModel();
_analyticsService.logProjectTrainModel();
String? projectId = currentProject?.get('id');
RouteNavigator.navigateTo(
route: Routes.projectsAppPreview,
......@@ -799,7 +807,7 @@ class ProjectProvider with ChangeNotifier {
var projectId = currentProject?.get('id');
if (datasetSummaries.containsKey(projectId)) {
DatasetSummary summaries = datasetSummaries[projectId]!;
AnalyticsService().logProjectLabelsOverview(
_analyticsService.logProjectLabelsOverview(
summaries.numLabeled.toString(),
summaries.numSkipped.toString(),
getDatasetSize().toString(),
......@@ -811,6 +819,16 @@ class ProjectProvider with ChangeNotifier {
param: {'id': projectId},
);
}
void onTapGoogleColabButton() {
_analyticsService.logProjectGoogleColab();
js.context.callMethod('open', [app.settings.colabLink]);
}
void onTapProjectPipeline(String? jobUrl) {
_analyticsService.logProjectGitlabPipelineUrl(jobUrl);
js.context.callMethod('open', [jobUrl]);
}
}
class DatasetSummary {
......
......@@ -88,12 +88,6 @@ class AppsScreenState extends State<AppsScreen> {
);
}
Widget _buildFeedTile() => _buildTile(
'Feeds',
'This is your default feed. It displays all social media from connected data streams.',
Routes.feed,
);
Widget _buildTile(String title, String description, String dest) {
return InkWell(
onTap: () => RouteNavigator.navigateTo(context: context, route: dest),
......@@ -130,12 +124,15 @@ class AppsScreenState extends State<AppsScreen> {
);
}
Widget _buildInboxTile() {
return _buildTile(
'Inbox',
'This is your default inbox app. It displays messages from all your connected data streams. You can send and receive messages directly within this app. You must connect at least one messenger or email importer to use this app.',
Routes.inbox);
}
Widget _buildInboxTile() => _buildTile(
'Inbox',
'This is your default inbox app. It displays messages from all your connected data streams. You can send and receive messages directly within this app. You must connect at least one messenger or email importer to use this app.',
Routes.inbox);
Widget _buildFeedTile() => _buildTile(
'Feeds',
'This is your default feed. It displays all social media from connected data streams.',
Routes.feed);
Widget _buildEmptyState() {
return Column(
......
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';
......@@ -142,19 +141,8 @@ class DataScreenState extends State<DataScreen> {
active: provider.isImporterActive(DataSource.whatsapp),
selected:
provider.isImporterSelected(DataSource.whatsapp),
onTap: () {
AnalyticsService().logImporterSelect('whatsapp');
if (!provider.isImporterActive(DataSource.whatsapp)) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerConnect,
param: {'name': 'whatsapp'},
);
} else {
provider.setActivePlugin(
provider.activePlugins[DataSource.whatsapp]);
}
},
onTap: () => provider.onTapImporterTile(
context, DataSource.whatsapp),
),
ImporterTile(
title: 'Twitter',
......@@ -166,19 +154,8 @@ class DataScreenState extends State<DataScreen> {
: null,
active: provider.isImporterActive(DataSource.twitter),
selected: provider.isImporterSelected(DataSource.twitter),
onTap: () {
AnalyticsService().logImporterSelect('twitter');
if (!provider.isImporterActive(DataSource.twitter)) {
RouteNavigator.navigateTo(
context: context,
route: Routes.importerConnect,
param: {'name': 'twitter'},
);
} else {
provider.setActivePlugin(
provider.activePlugins[DataSource.twitter]);
}
},
onTap: () => provider.onTapImporterTile(
context, DataSource.twitter),
),
ImporterTile(
title: 'Create new importer',
......
import 'dart:js' as js;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:memri/configs/routes/route_navigator.dart';
import 'package:memri/constants/app_logger.dart';
import 'package:memri/constants/app_styles.dart';
import 'package:memri/core/services/analytics_service.dart';
import 'package:memri/providers/oauth_provider.dart';
import 'package:memri/providers/pod_provider.dart';
import 'package:memri/providers/project_provider.dart';
......@@ -100,10 +97,7 @@ class _ProjectsAppCreateScreenState extends State<ProjectsAppCreateScreen> {
style: AppStyles.bodyText1),
SizedBox(height: 20),
TextButton(
onPressed: () {
AnalyticsService().logProjectGoogleColab();
js.context.callMethod('open', [app.settings.colabLink]);
},
onPressed: provider.onTapGoogleColabButton,
style: provider.projectHasPackage
? secondaryButtonStyle
: primaryButtonStyle,
......@@ -160,9 +154,8 @@ class _ProjectsAppCreateScreenState extends State<ProjectsAppCreateScreen> {
Row(
children: [
InkWell(
onTap: () => {
js.context.callMethod('open', [job.url])
},
onTap: () =>
provider.onTapProjectPipeline(job.url),
child: Container(
height: 40,
color: app.colors.greyBackGround,
......
......@@ -45,7 +45,7 @@ class _ProjectsAppPreviewScreen extends State<ProjectsAppPreviewScreen> {
var oAuthProvider = Provider.of<OAuthProvider>(context, listen: false);
await projectProvider.setCurrentMemriProject(context, widget.id);
oAuthProvider.setGitlabAccesTokenFromPod();
oAuthProvider.setGitlabAccessTokenFromPod();
await projectProvider.setGitlabProject();
dataAppProvider.currentGitProjectId = projectProvider.gitlabProjectId;
......
......@@ -182,11 +182,14 @@ class _ProjectsScreenState extends State<ProjectsScreen> {
var summary =
provider.datasetSummaries[projectId] ?? DatasetSummary();
return InkWell(
onTap: () => RouteNavigator.navigateTo(
context: context,
route: Routes.projectsSummary,
param: {'id': projectId},
),
onTap: () {
AnalyticsService().logProjectOpen(projectId);
RouteNavigator.navigateTo(
context: context,
route: Routes.projectsSummary,
param: {'id': projectId},
);
},
child: Container(
color: app.colors.white,
margin: EdgeInsets.only(bottom: 2),
......
......@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 2.2.7+0
version: 2.2.8+0
environment:
sdk: ">=2.12.0 <3.0.0"
......
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