// ignore_for_file: use_build_context_synchronously import 'package:extension_google_sign_in_as_googleapis_auth/extension_google_sign_in_as_googleapis_auth.dart'; import 'package:provider/provider.dart'; import 'package:refilc/api/providers/database_provider.dart'; import 'package:refilc/api/providers/user_provider.dart'; import 'package:refilc/models/linked_account.dart'; import 'package:refilc/models/settings.dart'; import 'package:refilc/models/user.dart'; import 'package:refilc_kreta_api/controllers/timetable_controller.dart'; import 'package:refilc_kreta_api/models/lesson.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'; class ThirdPartyProvider with ChangeNotifier { late List _linkedAccounts; // google specific late List? _googleEvents; late List _googleCalendars; late BuildContext _context; static final _googleSignIn = GoogleSignIn(scopes: [ CalendarApi.calendarScope, CalendarApi.calendarEventsScope, ]); // public List get linkedAccounts => _linkedAccounts; List get googleEvents => _googleEvents ?? []; List get googleCalendars => _googleCalendars; ThirdPartyProvider({ required BuildContext context, List? initialLinkedAccounts, }) { _context = context; _linkedAccounts = List.castFrom(initialLinkedAccounts ?? []); _googleCalendars = []; if (_linkedAccounts.isEmpty) restore(); if (_googleCalendars.isEmpty) fetchGoogle(); } Future restore() async { String? userId = Provider.of(_context, listen: false).id; // load accounts from db if (userId != null) { var dbLinkedAccounts = await Provider.of(_context, listen: false) .userQuery .getLinkedAccounts(userId: userId); _linkedAccounts = dbLinkedAccounts; // if (res == null) { // throw 'Google sign in failed, some data will be unavailable.'; // } notifyListeners(); } } Future store(List accounts) async { User? user = Provider.of(_context, listen: false).user; if (user == null) throw "Cannot store Linked Accounts for User null"; String userId = user.id; await Provider.of(_context, listen: false) .userStore .storeLinkedAccounts(accounts, userId: userId); _linkedAccounts = accounts; notifyListeners(); } void fetch() async {} Future googleSignIn() async { // signOutAll(); if (!await _googleSignIn.isSignedIn()) { GoogleSignInAccount? account = await _googleSignIn.signIn(); if (account == null) return null; LinkedAccount linked = LinkedAccount.fromJson({ 'type': 'google', 'username': account.email, 'display_name': account.displayName ?? '', 'id': account.id, }); _linkedAccounts.add(linked); store(_linkedAccounts); return account; } return null; } Future signOutAll() async { await _googleSignIn.signOut(); _linkedAccounts.clear(); } // Future 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 fetchGoogle() async { await _googleSignIn.signInSilently(); try { var httpClient = (await _googleSignIn.authenticatedClient())!; var calendarApi = CalendarApi(httpClient); _googleCalendars = (await calendarApi.calendarList.list()).items ?? []; if (kDebugMode) { print(_googleCalendars); } notifyListeners(); } catch (e) { if (kDebugMode) { print(e); } // await _googleSignIn.signOut(); } } Future pushEvent({ required String title, required String calendarId, required DateTime start, required DateTime end, required String description, required String? location, }) 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, description: description, location: location, ); return await calendarApi.events.insert(event, calendarId); } catch (e) { if (kDebugMode) print(e); await _googleSignIn.signOut(); } return null; } Future 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 getCalendar({ required String id, }) async { try { var httpClient = (await _googleSignIn.authenticatedClient())!; var calendarApi = CalendarApi(httpClient); return await calendarApi.calendars.get(id); } catch (e) { if (kDebugMode) print(e); await _googleSignIn.signOut(); } return null; } Future pushTimetable( BuildContext context, TimetableController controller) async { SettingsProvider settings = Provider.of(_context, listen: false); String calendarId = settings.calendarId; late Calendar? calendar; if (calendarId == '') { 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.', ); } else { calendar = await getCalendar(id: calendarId); } 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) { String mixedDescription = ''; if (settings.calSyncShowTeacher) { mixedDescription += 'Tanár: ${(l.teacher.isRenamed && settings.calSyncRenamed && settings.renamedTeachersEnabled) ? l.teacher.renamedTo : l.teacher.name}\n'; } if (settings.calSyncRoomLocation == 'description') { mixedDescription += 'Terem: ${l.room}\n'; } Event? event = await pushEvent( title: (((l.subject.isRenamed && settings.calSyncRenamed && settings.renamedSubjectsEnabled) ? l.subject.renamedTo : l.subject.name) ?? l.name) + (settings.calSyncShowExams && l.exam.replaceAll(' ', '') != '' ? '📝' : ''), calendarId: calendar.id!, start: l.start, end: l.end, description: mixedDescription, location: settings.calSyncRoomLocation == 'location' ? l.room : null, ); // temp shit (DONT BULLY ME, ILL CUM) if (kDebugMode) { if (false != true) print(event); } } return; // print('finished'); } }