first google calendar timetable sync demo done

This commit is contained in:
Kima 2024-02-11 19:39:33 +01:00
parent 404933168f
commit 35dc47fd62
8 changed files with 219 additions and 23 deletions

View File

@ -62,6 +62,13 @@ android {
} }
signingConfigs { signingConfigs {
debug {
keyAlias "androiddebugkey"
keyPassword "Jelszo123"
storeFile file("C:/Users/kima/debugkeystore.jks")
storePassword "Jelszo123"
}
release { release {
keyAlias keystoreProperties['keyAlias'] keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword'] keyPassword keystoreProperties['keyPassword']
@ -71,6 +78,10 @@ android {
} }
buildTypes { buildTypes {
debug {
signingConfig signingConfigs.debug
}
release { release {
signingConfig signingConfigs.release signingConfig signingConfigs.release
shrinkResources false shrinkResources false

View File

@ -12,6 +12,7 @@ import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/api/providers/self_note_provider.dart'; import 'package:filcnaplo/api/providers/self_note_provider.dart';
import 'package:filcnaplo/api/providers/status_provider.dart'; import 'package:filcnaplo/api/providers/status_provider.dart';
import 'package:filcnaplo/models/config.dart'; import 'package:filcnaplo/models/config.dart';
import 'package:filcnaplo/providers/third_party_provider.dart';
import 'package:filcnaplo/theme/observer.dart'; import 'package:filcnaplo/theme/observer.dart';
import 'package:filcnaplo/theme/theme.dart'; import 'package:filcnaplo/theme/theme.dart';
import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/client/client.dart';
@ -178,6 +179,11 @@ class App extends StatelessWidget {
ChangeNotifierProvider<SelfNoteProvider>( ChangeNotifierProvider<SelfNoteProvider>(
create: (context) => SelfNoteProvider(context: context), create: (context) => SelfNoteProvider(context: context),
), ),
// third party providers
ChangeNotifierProvider<ThirdPartyProvider>(
create: (context) => ThirdPartyProvider(context: context),
),
], ],
child: Consumer<ThemeModeObserver>( child: Consumer<ThemeModeObserver>(
builder: (context, themeMode, child) { builder: (context, themeMode, child) {

View File

@ -13,6 +13,9 @@ import 'package:flutter/services.dart';
import 'package:filcnaplo_mobile_ui/screens/error_screen.dart'; import 'package:filcnaplo_mobile_ui/screens/error_screen.dart';
import 'package:filcnaplo_mobile_ui/screens/error_report_screen.dart'; import 'package:filcnaplo_mobile_ui/screens/error_report_screen.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// import 'package:firebase_core/firebase_core.dart';
// import 'firebase_options.dart';
void main() async { void main() async {
// Initalize // Initalize
@ -112,6 +115,12 @@ class Startup {
initializationSettings, initializationSettings,
); );
} }
// if (Platform.isAndroid || Platform.isIOS) {
// await Firebase.initializeApp(
// options: DefaultFirebaseOptions.currentPlatform,
// );
// }
} }
} }

View File

@ -0,0 +1,133 @@
import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart';
import 'package:filcnaplo_kreta_api/controllers/timetable_controller.dart';
import 'package:filcnaplo_kreta_api/models/lesson.dart';
import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:googleapis/calendar/v3.dart';
import 'package:google_sign_in/google_sign_in.dart';
import 'package:provider/provider.dart';
class ThirdPartyProvider with ChangeNotifier {
late List<Event>? _googleEvents;
// late BuildContext _context;
static final _googleSignIn = GoogleSignIn(scopes: [
CalendarApi.calendarScope,
CalendarApi.calendarEventsScope,
]);
List<Event> get googleEvents => _googleEvents ?? [];
ThirdPartyProvider({
required BuildContext context,
}) {
// _context = context;
}
Future<GoogleSignInAccount?> googleSignIn() async {
if (!await _googleSignIn.isSignedIn()) {
return _googleSignIn.signIn();
}
return null;
}
// Future<void> fetchGoogle() async {
// try {
// var httpClient = (await _googleSignIn.authenticatedClient())!;
// var calendarApi = CalendarApi(httpClient);
// var calendarList = await calendarApi.calendarList.list();
// if (calendarList.items == null) return;
// if (calendarList.items!.isEmpty) return;
// _googleEvents = (await calendarApi.events.list(
// '13342d17fe1e68680c43c0c44dcb7e30cb0171cc4e4ee9ee13c9ff3082d3279c@group.calendar.google.com'))
// .items;
// print(calendarList.items!
// .map((e) => (e.id ?? 'noid') + '-' + (e.description ?? 'nodesc')));
// print(_googleEvents!.map((e) => e.toJson()));
// } catch (e) {
// print(e);
// await _googleSignIn.signOut();
// }
// }
Future<Event?> pushEvent({
required String title,
required String calendarId,
required DateTime start,
required DateTime end,
}) async {
try {
var httpClient = (await _googleSignIn.authenticatedClient())!;
var calendarApi = CalendarApi(httpClient);
Event event = Event(
created: DateTime.now(),
creator: EventCreator(self: true),
start: EventDateTime(dateTime: start),
end: EventDateTime(dateTime: end),
summary: title,
);
return await calendarApi.events.insert(event, calendarId);
} catch (e) {
if (kDebugMode) print(e);
await _googleSignIn.signOut();
}
return null;
}
Future<Calendar?> createCalendar({
required String name,
required String description,
}) async {
try {
var httpClient = (await _googleSignIn.authenticatedClient())!;
var calendarApi = CalendarApi(httpClient);
Calendar calendar = Calendar(
summary: name,
description: description,
timeZone: 'Europe/Budapest',
);
return await calendarApi.calendars.insert(calendar);
} catch (e) {
if (kDebugMode) print(e);
await _googleSignIn.signOut();
}
return null;
}
Future<void> pushTimetable(
BuildContext context, TimetableController controller) async {
Calendar? calendar = await createCalendar(
name: 'reFilc - Órarend',
description:
'Ez egy automatikusan generált naptár, melyet a reFilc hozott létre az órarend számára.',
);
if (calendar == null) return;
final days = controller.days!;
final everyLesson = days.expand((x) => x).toList();
everyLesson.sort((a, b) => a.start.compareTo(b.start));
for (Lesson l in everyLesson) {
Event? event = await pushEvent(
title: l.name,
calendarId: calendar.id!,
start: l.start,
end: l.end,
);
}
print('finished');
}
}

View File

@ -72,6 +72,10 @@ dependencies:
image_crop: image_crop:
git: git:
url: https://github.com/kimaah/image_crop.git url: https://github.com/kimaah/image_crop.git
googleapis: ^12.0.0
google_sign_in: ^6.2.1
extension_google_sign_in_as_googleapis_auth: ^2.0.12
firebase_core: ^2.25.4
dev_dependencies: dev_dependencies:
flutter_lints: ^3.0.1 flutter_lints: ^3.0.1

View File

@ -2,6 +2,7 @@ import 'dart:math';
import 'package:animations/animations.dart'; import 'package:animations/animations.dart';
import 'package:filcnaplo/api/providers/update_provider.dart'; import 'package:filcnaplo/api/providers/update_provider.dart';
import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/providers/third_party_provider.dart';
import 'package:filcnaplo/utils/format.dart'; import 'package:filcnaplo/utils/format.dart';
import 'package:filcnaplo_kreta_api/client/client.dart'; import 'package:filcnaplo_kreta_api/client/client.dart';
import 'package:filcnaplo_kreta_api/models/week.dart'; import 'package:filcnaplo_kreta_api/models/week.dart';
@ -210,30 +211,37 @@ class TimetablePageState extends State<TimetablePage>
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: IconButton( child: IconButton(
splashRadius: 24.0, splashRadius: 24.0,
onPressed: () { onPressed: () async {
// If timetable empty, show empty ThirdPartyProvider tpp =
if (_tabController.length == 0) { Provider.of<ThirdPartyProvider>(context,
ScaffoldMessenger.of(context).showSnackBar(SnackBar( listen: false);
content: Text("empty_timetable".i18n),
duration: const Duration(seconds: 2),
));
return;
}
Navigator.of(context, rootNavigator: true) await tpp.pushTimetable(context, _controller);
.push(PageRouteBuilder(
pageBuilder:
(context, animation, secondaryAnimation) =>
FSTimetable(
controller: _controller,
),
))
.then((_) {
SystemChrome.setPreferredOrientations(
[DeviceOrientation.portraitUp]);
setSystemChrome(context);
});
}, },
// onPressed: () {
// // If timetable empty, show empty
// if (_tabController.length == 0) {
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
// content: Text("empty_timetable".i18n),
// duration: const Duration(seconds: 2),
// ));
// return;
// }
// Navigator.of(context, rootNavigator: true)
// .push(PageRouteBuilder(
// pageBuilder:
// (context, animation, secondaryAnimation) =>
// FSTimetable(
// controller: _controller,
// ),
// ))
// .then((_) {
// SystemChrome.setPreferredOrientations(
// [DeviceOrientation.portraitUp]);
// setSystemChrome(context);
// });
// },
icon: Icon(FeatherIcons.trello, icon: Icon(FeatherIcons.trello,
color: AppColors.of(context).text), color: AppColors.of(context).text),
), ),

View File

@ -1,6 +1,7 @@
// ignore_for_file: no_leading_underscores_for_local_identifiers, use_build_context_synchronously, deprecated_member_use // ignore_for_file: no_leading_underscores_for_local_identifiers, use_build_context_synchronously, deprecated_member_use
import 'package:filcnaplo/api/providers/update_provider.dart'; import 'package:filcnaplo/api/providers/update_provider.dart';
import 'package:filcnaplo/providers/third_party_provider.dart';
import 'package:filcnaplo/theme/colors/accent.dart'; import 'package:filcnaplo/theme/colors/accent.dart';
import 'package:filcnaplo/theme/observer.dart'; import 'package:filcnaplo/theme/observer.dart';
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
@ -1095,6 +1096,30 @@ class SettingsScreenState extends State<SettingsScreen>
], ],
), ),
if (kDebugMode)
SplittedPanel(
title: const Text("debug_settings"),
cardPadding: const EdgeInsets.all(4.0),
children: [
PanelButton(
title: const Text('loginToGoogle'),
onPressed: () async {
ThirdPartyProvider tpp = Provider.of<ThirdPartyProvider>(
context,
listen: false);
await tpp.googleSignIn();
},
),
PanelButton(
title: const Text('pushTimetableToCalendar'),
onPressed: () async {
},
),
],
),
// developer options // developer options
if (settings.developerMode) if (settings.developerMode)
SplittedPanel( SplittedPanel(

@ -1 +1 @@
Subproject commit 5d73a83c7d1f8925ef20d919ed31f583d1303d23 Subproject commit 534f4a66216a84af13d4a0b28e745e5ec8c335d0