Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="ins"
android:name="${applicationName}"
Expand Down
4 changes: 4 additions & 0 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ import 'package:ins/locale.dart' as locale_manager; // Aliased
import 'package:provider/provider.dart';
import 'package:ins/widgets/loading.dart';

final version = "v1.0.0";
final versionShort = "v1.0";
final apiVersion = "v1";

class ISApp extends StatelessWidget {
const ISApp({super.key});

Expand Down
4 changes: 2 additions & 2 deletions lib/pages/sign/signup/launcher.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:flutter/material.dart';
import 'namepassword.dart';
import 'package:ins/pages/sign/signup/terms.dart';
import 'form.dart';
import 'package:ins/animations/page/slide.dart';

void launchSignupAssistant(BuildContext context) {
SignupForm form = SignupForm();

Navigator.push(context, SlidePageRoute(child: NamePasswordPage(form: form)));
Navigator.push(context, SlidePageRoute(child: TermsPage(form: form)));
}
165 changes: 165 additions & 0 deletions lib/pages/sign/signup/terms.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:ins/utils/terms.dart' as terms;
import 'package:ins/widgets/imsg.dart';
import 'package:ins/widgets/loading.dart';
import 'form.dart';
import 'base.dart';
import 'namepassword.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:ins/l10n/app_localizations.dart';

class TermsPage extends StatelessWidget {
final SignupForm form;
const TermsPage({super.key, required this.form});

@override
Widget build(BuildContext context) {
final locale = Localizations.localeOf(context).languageCode;
return FutureBuilder(
future: terms.getTerms(locale, "md"),
builder: (context, snapshot) {
if (snapshot.hasData) {
return TermsWidget(form: form, termsMarkdown: snapshot.data!);
} else if (snapshot.connectionState == ConnectionState.waiting) {
return Scaffold(
appBar: AppBar(title: Text("Loading terms ")),
body: LoadingWidget(
messages: AppLocalizations.of(
context,
)!.waitingMessages.split("|"),
),
);
} else {
return Scaffold(
appBar: AppBar(title: Text("Error")),
body: IMsgWidget(
icon: Icon(Icons.error_rounded, size: 150, color: Colors.red),
message: Text(snapshot.error.toString()),
),
);
}
},
);
}
}

class TermsWidget extends StatefulWidget {
final SignupForm form;
final String termsMarkdown;
const TermsWidget({
super.key,
required this.form,
required this.termsMarkdown,
});

@override
State<TermsWidget> createState() => _TermsWidgetState();
}

class _TermsWidgetState extends State<TermsWidget> {
bool _termsAccepted = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Terms & Conditions")),
body: Padding(
padding: const EdgeInsets.fromLTRB(
16.0,
16.0,
16.0,
24.0,
), // More bottom padding
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
"Please review and accept our terms and conditions to continue.",
style: Theme.of(context).textTheme.titleMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
Expanded(
child: Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey.shade300),
borderRadius: BorderRadius.circular(8.0),
),
child: ClipRRect(
// Ensures scrollbar is also clipped by border radius
borderRadius: BorderRadius.circular(
7.0,
), // slightly less than container
child: Scrollbar(
thumbVisibility: true,
child: SingleChildScrollView(
padding: const EdgeInsets.all(12.0),
child: MarkdownBody(
data: widget.termsMarkdown,
selectable: true, // Allows users to select text
styleSheet:
MarkdownStyleSheet.fromTheme(
Theme.of(context),
).copyWith(
// Improve theme
p: Theme.of(context).textTheme.bodyMedium
?.copyWith(fontSize: 15, height: 1.5),
h1: Theme.of(context).textTheme.headlineSmall
?.copyWith(fontWeight: FontWeight.bold),
h2: Theme.of(context).textTheme.titleLarge
?.copyWith(fontWeight: FontWeight.w600),
// Add more custom styles if needed
),
onTapLink: (text, href, title) {
if (href == null) return;
launchUrl(Uri.parse(href));
},
),
),
),
),
),
),
const SizedBox(height: 16),
CheckboxListTile(
title: const Text(
"I have read and agree to the terms and conditions.",
),
value: _termsAccepted,
onChanged: (bool? value) {
setState(() {
_termsAccepted = value ?? false;
});
},
controlAffinity: ListTileControlAffinity.leading,
contentPadding: EdgeInsets.zero,
activeColor: Theme.of(context).colorScheme.primary,
dense: true,
),
const SizedBox(height: 24.0), // Spacing before the button
FilledButton(
onPressed: _termsAccepted
? () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (context) =>
NamePasswordPage(form: widget.form),
),
);
}
: null,
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16.0),
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: Text("Accept & Continue"),
),
],
),
),
);
}
}
27 changes: 27 additions & 0 deletions lib/utils/terms.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:http/http.dart' as http;
import 'package:ins/app.dart' as app;

String getDocUrl(String version, String doc, String lang, String format) {
final url =
"https://raw.githubusercontent.com/recordbreakersorg/docs/main/ins/$version/$doc/$lang.$format";
print(url);
return url;
}

Future<String> getTerms(String lang, String format) async {
late http.Response response;
try {
response = await http.get(
Uri.parse(getDocUrl(app.version, "terms", lang, format)),
);
} catch (e) {
throw Exception("Could not get terms of service: $e");
}
if (response.statusCode == 200) {
return response.body;
} else {
throw Exception(
'Failed to load data from backend, invalid status code: ${response.statusCode}',
);
}
}
4 changes: 3 additions & 1 deletion lib/widgets/imsg.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ class IMsgWidget extends StatelessWidget {
final Icon icon;
final Text message;
final Widget? actions;
final bool spacer;
const IMsgWidget({
super.key,
required this.icon,
required this.message,
this.actions = const SizedBox.shrink(),
this.spacer = true,
});
@override
Widget build(BuildContext context) {
Expand All @@ -24,7 +26,7 @@ class IMsgWidget extends StatelessWidget {
icon,
SizedBox(height: 20),
message,
Spacer(),
if (spacer) Spacer(),
if (actions != null)
SizedBox(width: double.infinity, child: actions!),
const SizedBox(height: 20),
Expand Down
4 changes: 4 additions & 0 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

#include "generated_plugin_registrant.h"

#include <url_launcher_linux/url_launcher_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}
1 change: 1 addition & 0 deletions linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import Foundation
import path_provider_foundation
import shared_preferences_foundation
import sqflite_darwin
import url_launcher_macos

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
80 changes: 80 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_markdown:
dependency: "direct main"
description:
name: flutter_markdown
sha256: "08fb8315236099ff8e90cb87bb2b935e0a724a3af1623000a9cec930468e0f27"
url: "https://pub.dev"
source: hosted
version: "0.7.7+1"
flutter_test:
dependency: "direct dev"
description: flutter
Expand Down Expand Up @@ -317,6 +325,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.1"
markdown:
dependency: transitive
description:
name: markdown
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
url: "https://pub.dev"
source: hosted
version: "7.3.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -634,6 +650,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
url_launcher:
dependency: "direct main"
description:
name: url_launcher
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
name: url_launcher_android
sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79"
url: "https://pub.dev"
source: hosted
version: "6.3.16"
url_launcher_ios:
dependency: transitive
description:
name: url_launcher_ios
sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb"
url: "https://pub.dev"
source: hosted
version: "6.3.3"
url_launcher_linux:
dependency: transitive
description:
name: url_launcher_linux
sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
url: "https://pub.dev"
source: hosted
version: "3.2.1"
url_launcher_macos:
dependency: transitive
description:
name: url_launcher_macos
sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2"
url: "https://pub.dev"
source: hosted
version: "3.2.2"
url_launcher_platform_interface:
dependency: transitive
description:
name: url_launcher_platform_interface
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted
version: "2.3.2"
url_launcher_web:
dependency: transitive
description:
name: url_launcher_web
sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
url: "https://pub.dev"
source: hosted
version: "3.1.4"
uuid:
dependency: transitive
description:
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ dependencies:
sdk: flutter
intl: any
provider: ^6.1.5
flutter_markdown: ^0.7.7+1
url_launcher: ^6.3.1

dev_dependencies:
flutter_test:
Expand Down
Loading