Skip to content

Commit dda362f

Browse files
committed
Added analytics and minor design fixes
1 parent 79e0053 commit dda362f

14 files changed

+209
-63
lines changed
160 KB
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

lib/analytics.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
library wsl2distromanager.analytics;
2+
3+
import 'package:plausible_analytics/plausible_analytics.dart';
4+
5+
String analyticsUrl = "https://analytics.bostrot.com";
6+
const String analyticsName = "wslmanager.bostrot.com";
7+
8+
Plausible plausible = Plausible(analyticsUrl, analyticsName);

lib/api.dart

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class App {
4242
}
4343
}
4444
} catch (e) {
45-
print(e);
45+
// ignored
4646
}
4747
return '';
4848
}
@@ -54,11 +54,10 @@ class App {
5454
if (response.data.length > 0) {
5555
var jsonData = json.decode(response.data);
5656
String motd = jsonData['motd'];
57-
print(motd);
5857
return motd;
5958
}
6059
} catch (e) {
61-
print(e);
60+
// ignored
6261
}
6362
return '';
6463
}
@@ -106,7 +105,6 @@ class WSLApi {
106105
if (location == '') {
107106
location = 'C:\\WSL2-Distros\\';
108107
}
109-
print("$distribution, $location + $distribution + '.tar'");
110108
String exportRes =
111109
await export(distribution, location + distribution + '.tar');
112110
String importRes = await import(

lib/dialog.dart

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:fluent_ui/fluent_ui.dart';
22
import 'api.dart';
3+
import 'analytics.dart';
34

45
dialog({
56
required BuildContext context,
@@ -12,8 +13,11 @@ dialog({
1213
String submitText = '',
1314
ButtonStyle submitStyle = const ButtonStyle(),
1415
bool submitInput = true,
16+
String cancelText = 'Cancel',
17+
Function? onCancel,
1518
}) {
1619
final controller = TextEditingController();
20+
plausible.event(page: title.split(' ')[0].toLowerCase());
1721
showDialog(
1822
context: context,
1923
builder: (context) {
@@ -42,8 +46,11 @@ dialog({
4246
onSubmit(controller.text);
4347
}),
4448
Button(
45-
child: const Text('Cancel'),
49+
child: Text(cancelText),
4650
onPressed: () {
51+
if (onCancel != null) {
52+
onCancel();
53+
}
4754
Navigator.pop(context);
4855
}),
4956
],

lib/distro_create_component.dart

Lines changed: 33 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'analytics.dart';
12
import 'api.dart';
23
import 'package:fluent_ui/fluent_ui.dart';
34
import 'package:file_picker/file_picker.dart';
@@ -31,54 +32,39 @@ Widget createComponent(WSLApi api, Function(String, {bool loading}) statusMsg) {
3132
child: FutureBuilder<List<String>>(
3233
future: api.getDownloadable(),
3334
builder: (context, snapshot) {
35+
List<String> list = [];
3436
if (snapshot.hasData) {
35-
List<String> list = snapshot.data ?? [];
36-
return AutoSuggestBox<String>(
37-
controller: autoSuggestBox,
38-
items: list,
39-
onSelected: (text) {
40-
print(text);
41-
},
42-
textBoxBuilder: (context, controller, focusNode, key) {
43-
return TextBox(
44-
key: key,
45-
controller: controller,
46-
focusNode: focusNode,
47-
suffix: Row(children: [
48-
IconButton(
49-
icon: const Icon(FluentIcons.close, size: 15.0),
50-
onPressed: () {
51-
controller.clear();
52-
focusNode.unfocus();
53-
},
54-
),
55-
IconButton(
56-
icon: const Icon(FluentIcons.open_folder_horizontal,
57-
size: 15.0),
58-
onPressed: () async {
59-
FilePickerResult? result =
60-
await FilePicker.platform.pickFiles(
61-
type: FileType.custom,
62-
allowedExtensions: ['*'],
63-
);
37+
list = snapshot.data ?? [];
38+
} else if (snapshot.hasError) {}
39+
return AutoSuggestBox<String>(
40+
controller: autoSuggestBox,
41+
items: list,
42+
textBoxBuilder: (context, controller, focusNode, key) {
43+
return TextBox(
44+
key: key,
45+
controller: controller,
46+
focusNode: focusNode,
47+
suffix: IconButton(
48+
icon: const Icon(FluentIcons.open_folder_horizontal,
49+
size: 15.0),
50+
onPressed: () async {
51+
FilePickerResult? result =
52+
await FilePicker.platform.pickFiles(
53+
type: FileType.custom,
54+
allowedExtensions: ['*'],
55+
);
6456

65-
if (result != null) {
66-
controller.text = result.files.single.path!;
67-
} else {
68-
// User canceled the picker
69-
}
70-
},
71-
),
72-
]),
73-
placeholder: 'Distro',
74-
);
75-
},
76-
);
77-
} else if (snapshot.hasError) {
78-
return Text('${snapshot.error}');
79-
}
80-
// By default, show a loading spinner.
81-
return const Center(child: ProgressRing());
57+
if (result != null) {
58+
controller.text = result.files.single.path!;
59+
} else {
60+
// User canceled the picker
61+
}
62+
},
63+
),
64+
placeholder: 'Distro',
65+
);
66+
},
67+
);
8268
}),
8369
)),
8470
Expanded(
@@ -103,6 +89,7 @@ Widget createComponent(WSLApi api, Function(String, {bool loading}) statusMsg) {
10389
),
10490
Button(
10591
onPressed: () async {
92+
plausible.event(name: "wsl_create");
10693
List<String> downloadable = await api.getDownloadable();
10794

10895
if (nameController.text != '') {

lib/distro_list_component.dart

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
import 'package:flutter/gestures.dart';
2-
1+
import 'analytics.dart';
32
import 'api.dart';
43
import 'dialog.dart';
54
import 'package:fluent_ui/fluent_ui.dart';
65

76
class DistroList extends StatefulWidget {
8-
DistroList(
9-
{Key? key,
10-
required WSLApi this.api,
11-
required Function(String, {bool loading}) this.statusMsg})
7+
const DistroList({Key? key, required this.api, required this.statusMsg})
128
: super(key: key);
139

1410
final WSLApi api;
@@ -77,6 +73,7 @@ FutureBuilder<Instances> distroList(
7773
child: IconButton(
7874
icon: const Icon(FluentIcons.play),
7975
onPressed: () {
76+
plausible.event(name: "wsl_started");
8077
api.start(item);
8178
Future.delayed(const Duration(milliseconds: 500),
8279
statusMsg('$item started.'));
@@ -89,6 +86,7 @@ FutureBuilder<Instances> distroList(
8986
child: IconButton(
9087
icon: const Icon(FluentIcons.stop),
9188
onPressed: () {
89+
plausible.event(name: "wsl_stopped");
9290
api.stop(item);
9391
statusMsg('$item stopped.');
9492
},
@@ -103,6 +101,7 @@ FutureBuilder<Instances> distroList(
103101
child: IconButton(
104102
icon: const Icon(FluentIcons.open_folder_horizontal),
105103
onPressed: () async {
104+
plausible.event(name: "wsl_explorer");
106105
api.startExplorer(item);
107106
},
108107
),
@@ -112,6 +111,7 @@ FutureBuilder<Instances> distroList(
112111
child: IconButton(
113112
icon: const Icon(FluentIcons.visual_studio_for_windows),
114113
onPressed: () async {
114+
plausible.event(name: "wsl_vscode");
115115
api.startVSCode(item);
116116
},
117117
),

lib/main.dart

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,31 @@
1-
import 'package:desktop_window/desktop_window.dart';
1+
//import 'package:desktop_window/desktop_window.dart';
22
import 'package:fluent_ui/fluent_ui.dart';
33
import 'package:url_launcher/url_launcher.dart';
44
import 'package:system_theme/system_theme.dart';
55
import 'package:bitsdojo_window/bitsdojo_window.dart';
6+
import 'package:shared_preferences/shared_preferences.dart';
67

78
import 'api.dart';
9+
import 'dialog.dart';
810
import 'distro_list_component.dart';
911
import 'distro_create_component.dart';
1012

13+
import 'analytics.dart';
14+
1115
// TODO: Update on release
1216
const String currentVersion = "v0.5.2+1";
17+
const String windowsStoreUrl = "https://www.microsoft.com/store/"
18+
"productId/9NWS9K95NMJB";
1319

14-
const String windowsStoreUrl =
15-
'https://www.microsoft.com/store/productId/9NWS9K95NMJB';
20+
late SharedPreferences prefs;
1621

1722
void main() async {
1823
WidgetsFlutterBinding.ensureInitialized();
1924
await SystemTheme.accentInstance.load();
2025
runApp(const MyApp());
2126
doWhenWindowReady(() {
2227
final win = appWindow;
23-
final initialSize = Size(650, 500);
28+
const initialSize = Size(650, 500);
2429
win.minSize = initialSize;
2530
win.size = initialSize;
2631
win.alignment = Alignment.center;
@@ -29,6 +34,15 @@ void main() async {
2934
});
3035
//DesktopWindow.setWindowSize(const Size(650, 500));
3136
//DesktopWindow.setMinWindowSize(const Size(650, 500));
37+
38+
prefs = await SharedPreferences.getInstance();
39+
bool? privacyMode = prefs.getBool('privacyMode');
40+
if (privacyMode != null && privacyMode) {
41+
plausible.enabled = false;
42+
}
43+
44+
// Enable analytics
45+
plausible.event();
3246
}
3347

3448
ThemeData themeData = ThemeData();
@@ -130,7 +144,6 @@ class _MyHomePageState extends State<MyHomePage> {
130144

131145
// Check motd
132146
app.checkMotd().then((String motd) {
133-
print(motd);
134147
statusMsg(motd, leadingIcon: false);
135148
});
136149
}
@@ -241,6 +254,7 @@ class _MyHomePageState extends State<MyHomePage> {
241254
children: [
242255
TextButton(
243256
onPressed: () async {
257+
plausible.event(name: "url_clicked");
244258
await canLaunch('https://bostrot.com')
245259
? await launch('https://bostrot.com')
246260
: throw 'Could not launch URL';
@@ -250,6 +264,7 @@ class _MyHomePageState extends State<MyHomePage> {
250264
const Text('|', style: TextStyle(fontSize: 12.0)),
251265
TextButton(
252266
onPressed: () async {
267+
plausible.event(name: "git_clicked");
253268
await canLaunch(
254269
'https://github.com/bostrot/wsl2-distro-manager')
255270
? await launch(
@@ -261,12 +276,43 @@ class _MyHomePageState extends State<MyHomePage> {
261276
const Text('|', style: TextStyle(fontSize: 12.0)),
262277
TextButton(
263278
onPressed: () async {
279+
plausible.event(name: "donate_clicked");
264280
await canLaunch('http://paypal.me/bostrot')
265281
? await launch('http://paypal.me/bostrot')
266282
: throw 'Could not launch URL';
267283
},
268284
child:
269285
const Text("Donate", style: TextStyle(fontSize: 12.0))),
286+
const Text('|', style: TextStyle(fontSize: 12.0)),
287+
TextButton(
288+
onPressed: () async {
289+
plausible.event(name: "analytics_clicked");
290+
dialog(
291+
context: context,
292+
item: "Allow",
293+
api: api,
294+
statusMsg: statusMsg,
295+
title: 'Usage Data',
296+
body: 'Do you want to share anonymous usage data to '
297+
'improve this app?',
298+
submitText: 'Enable privacy mode',
299+
submitInput: false,
300+
submitStyle: const ButtonStyle(),
301+
cancelText: 'Share usage data',
302+
onCancel: () async {
303+
plausible.event(name: "privacy_off");
304+
await prefs.setBool('privacyMode', false);
305+
plausible.enabled = true;
306+
},
307+
onSubmit: (inputText) async {
308+
plausible.event(name: "privacy_on");
309+
await prefs.setBool('privacyMode', true);
310+
plausible.enabled = false;
311+
statusMsg('Privacy mode enabled.');
312+
});
313+
},
314+
child:
315+
const Text("Privacy", style: TextStyle(fontSize: 12.0))),
270316
],
271317
)
272318
],

0 commit comments

Comments
 (0)