Compare commits

...

16 Commits
4.2.1 ... 4.2.2

Author SHA1 Message Date
Márton Kiss
023329f021 Merge pull request #43 from refilc/dev
Dev
2023-09-05 22:06:51 +02:00
Kima
e66fdbaeac added expire date to ads 2023-09-05 21:59:53 +02:00
Kima
bbbaea9224 fixed ad isBefore 2023-09-05 21:55:51 +02:00
Márton Kiss
c7c18cf684 Merge pull request #42 from refilc/dev
changed version number
2023-09-05 21:23:48 +02:00
Kima
4d501fed3e changed version number 2023-09-05 21:23:30 +02:00
Márton Kiss
8168ef5329 Merge pull request #41 from refilc/dev
Dev
2023-09-05 21:18:27 +02:00
Kima
608bc58771 fixed padding on ad tile 2023-09-05 21:17:54 +02:00
Kima
2cba1ec286 ads api working 2023-09-05 21:08:06 +02:00
Kima
b6eb65814f Merge branch 'dev' of github.com:refilc/naplo into dev 2023-09-05 18:49:16 +02:00
Kima
a5a43ea0b9 added ad provider 2023-09-05 18:49:14 +02:00
Márton Kiss
da356bb212 Merge pull request #40 from refilc/dev
Dev
2023-09-04 23:15:01 +02:00
Márton Kiss
c29ab3de29 Merge pull request #39 from Monke14/dev
Android widget fix
2023-09-04 23:14:38 +02:00
Kima
fceb4e050f FINALLY FIXED AUTO UPDATE 2023-09-04 23:13:54 +02:00
Kima
8feea02f68 added api endpoint and auto update fix 2023-09-04 21:45:11 +02:00
hihihaha
939e4f4d48 widget fix 2023-09-04 21:31:50 +02:00
Kima
a401ff32d9 something 2023-09-04 20:17:38 +02:00
27 changed files with 362 additions and 151 deletions

29
.vscode/launch.json vendored
View File

@@ -10,17 +10,16 @@
"--dart-define=APPVER=$(cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1)"
]
},
{
"name": "filcnaplo release",
"cwd": "filcnaplo release",
"request": "launch",
"type": "dart",
"flutterMode": "release",
"program": "lib/main.dart",
"toolArgs": [
"--dart-define=APPVER=$(cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1)"
]
},
// {
// "name": "filcnaplo release",
// "cwd": "filcnaplo release",
// "request": "launch",
// "type": "dart",
// "program": "lib/main.dart",
// "toolArgs": [
// "--dart-define=APPVER=$(cat pubspec.yaml | grep version: | cut -d' ' -f2 | cut -d+ -f1)"
// ]
// },
{
"name": "Flutter",
"program": "lib/main.dart",
@@ -28,6 +27,14 @@
"request": "launch",
"type": "dart",
"flutterMode": "debug"
},
{
"name": "Flutter (release)",
"program": "lib/main.dart",
"cwd": "filcnaplo",
"request": "launch",
"type": "dart",
"flutterMode": "release"
}
]
}

View File

@@ -26,6 +26,11 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.HashMap;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import hu.refilc.naplo.database.DBManager;
import hu.refilc.naplo.MainActivity;
@@ -247,71 +252,61 @@ public class WidgetTimetable extends HomeWidgetProvider {
}
public static List<JSONArray> genJsonDays(Context context) {
List<JSONArray> gen_days = new ArrayList<>();
List<JSONArray> genDays = new ArrayList<>();
Map<String, JSONArray> dayMap = new HashMap<>();
DBManager dbManager = new DBManager(context.getApplicationContext());
try {
dbManager.open();
Cursor ct = dbManager.fetchTimetable();
dbManager.close();
if(ct.getCount() == 0) {
return gen_days;
if (ct.getCount() == 0) {
return genDays;
}
JSONObject fecthtt = new JSONObject(ct.getString(0));
JSONObject fetchedTimetable = new JSONObject(ct.getString(0));
String currentWeek = String.valueOf(Week.current().id());
JSONArray week = fetchedTimetable.getJSONArray(currentWeek);
JSONArray dayArray = new JSONArray();
String currday = "";
String currweek = String.valueOf(Week.current().id());
JSONArray week = fecthtt.getJSONArray(currweek);
for (int i=0; i < week.length(); i++)
{
// Organize lessons into dates
for (int i = 0; i < week.length(); i++) {
try {
if(i == 0) currday = week.getJSONObject(0).getString("Datum");
JSONObject oraObj = week.getJSONObject(i);
if(!currday.equals(oraObj.getString("Datum"))) {
gen_days.add(dayArray);
currday = week.getJSONObject(i).getString("Datum");
dayArray = new JSONArray();
}
dayArray.put(oraObj);
if(i == week.length() - 1) {
gen_days.add(dayArray);
}
} catch (Exception e) {
JSONObject entry = week.getJSONObject(i);
String date = entry.getString("Datum");
dayMap.computeIfAbsent(date, k -> new JSONArray()).put(entry);
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
Collections.sort(gen_days, new Comparator<JSONArray>() {
public int compare(JSONArray a, JSONArray b) {
long valA = 0;
long valB = 0;
genDays.addAll(dayMap.values());
// Sort the 'genDays' list of JSON based on the start time of the first entry
genDays.sort((day1, day2) -> {
try {
valA = (long) new DateTime( a.getJSONObject(0).getString("Datum")).getMillis();
valB = (long) new DateTime( b.getJSONObject(0).getString("Datum")).getMillis();
}
catch (JSONException ignored) {
}
return (int) (valA - valB);
// Extract the start time of the first entry in each day's JSON
String startTime1 = day1.getJSONObject(0).getString("KezdetIdopont");
String startTime2 = day2.getJSONObject(0).getString("KezdetIdopont");
// Compare the start times and return the result for sorting
return startTime1.compareTo(startTime2);
} catch (JSONException e) {
e.printStackTrace();
return 0;
}
});
return gen_days;
} catch (Exception e) {
e.printStackTrace();
} finally {
dbManager.close();
}
return genDays;
}
public static String zeroPad(int value, int padding){
StringBuilder b = new StringBuilder();
b.append(value);

View File

@@ -335,10 +335,12 @@ public class WidgetTimetableDataProvider implements RemoteViewsService.RemoteVie
public Lesson jsonToLesson(JSONObject json) {
try {
String name = json.getString("Nev");
name = name.substring(0, 1).toUpperCase() + name.substring(1); // Capitalize name
return new Lesson(
json.getJSONObject("Allapot").getString("Nev"),
!json.getString("Oraszam").equals("null") ? json.getString("Oraszam") : "+",
json.getString("Nev"),
name,
json.getString("Tema"),
json.getString("TeremNeve"),
new DateTime(json.getString("KezdetIdopont")).getMillis(),

View File

@@ -1,15 +1,14 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/kima/development/flutter
FLUTTER_ROOT=/Users/kima/src/flutter
FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=/Users/kima/Documents/refilc/app/naplo/filcnaplo/lib/main.dart
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=3.5.1
FLUTTER_BUILD_NUMBER=197
FLUTTER_BUILD_NAME=4.2.0
FLUTTER_BUILD_NUMBER=220
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC9iNGZiMTEyMTRkZDJkZGE2Y2UwMTJkZDk4ZWE0OThlOWU4YjkxMjYyLw==
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=/Users/kima/Documents/refilc/app/naplo/filcnaplo/.dart_tool/package_config.json
PACKAGE_CONFIG=.dart_tool/package_config.json

View File

@@ -1,15 +1,14 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/kima/development/flutter
FLUTTER_ROOT=/Users/kima/src/flutter
FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=/Users/kima/Documents/refilc/app/naplo/filcnaplo/lib/main.dart
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=4.1.0
FLUTTER_BUILD_NUMBER=213
FLUTTER_BUILD_NAME=4.2.0
FLUTTER_BUILD_NUMBER=220
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC8yYTM0MDFjOWJiYjVhOWE5YWVjNzRkNGY3MzVkMThhOWRkM2ViZjJkLw==
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=/Users/kima/Documents/refilc/app/naplo/filcnaplo/.dart_tool/package_config.json
PACKAGE_CONFIG=.dart_tool/package_config.json

View File

@@ -1,15 +0,0 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/kima/src/flutter
FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=/Users/kima/Documents/refilc/app/naplo/filcnaplo/lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=4.1.1
FLUTTER_BUILD_NUMBER=216
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_DEFINES=QVBQVkVSPTQuMS4x,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC9jZGJlZGE3ODhhMjkzZmEyOTY2NWRjM2ZhM2Q2ZTYzYmQyMjFjYjBkLw==
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=/Users/kima/Documents/refilc/app/naplo/filcnaplo/.dart_tool/package_config.json

View File

@@ -1,14 +0,0 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/kima/src/flutter
FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=4.2.0
FLUTTER_BUILD_NUMBER=220
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json

View File

@@ -1,14 +1,13 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/kima/development/flutter"
export "FLUTTER_ROOT=/Users/kima/src/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=/Users/kima/Documents/refilc/app/naplo/filcnaplo/lib/main.dart"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=4.1.0"
export "FLUTTER_BUILD_NUMBER=213"
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ==,RkxVVFRFUl9XRUJfQ0FOVkFTS0lUX1VSTD1odHRwczovL3d3dy5nc3RhdGljLmNvbS9mbHV0dGVyLWNhbnZhc2tpdC8yYTM0MDFjOWJiYjVhOWE5YWVjNzRkNGY3MzVkMThhOWRkM2ViZjJkLw=="
export "FLUTTER_BUILD_NAME=4.2.0"
export "FLUTTER_BUILD_NUMBER=220"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=/Users/kima/Documents/refilc/app/naplo/filcnaplo/.dart_tool/package_config.json"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

View File

@@ -1,13 +0,0 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/kima/src/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/kima/Documents/refilc/app/naplo/filcnaplo"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=4.2.0"
export "FLUTTER_BUILD_NUMBER=220"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

View File

@@ -1,6 +1,7 @@
import 'dart:convert';
import 'dart:developer';
import 'package:filcnaplo/models/ad.dart';
import 'package:filcnaplo/models/config.dart';
import 'package:filcnaplo/models/news.dart';
import 'package:filcnaplo/models/release.dart';
@@ -18,6 +19,7 @@ class FilcAPI {
static const supporters = "https://api.refilc.hu/v1/public/supporters";
// Private API
static const ads = "https://api.refilc.hu/v1/private/ads";
static const config = "https://api.refilc.hu/v1/private/config";
static const reportApi = "https://api.refilc.hu/v1/private/crash-report";
static const premiumApi = "https://api.filcnaplo.hu/premium/activate";
@@ -117,6 +119,24 @@ class FilcAPI {
return null;
}
static Future<List<Ad>?> getAds() async {
try {
http.Response res = await http.get(Uri.parse(ads));
if (res.statusCode == 200) {
return (jsonDecode(res.body) as List)
.cast<Map>()
.map((e) => Ad.fromJson(e))
.toList();
} else {
throw "HTTP ${res.statusCode}: ${res.body}";
}
} on Exception catch (error, stacktrace) {
log("ERROR: FilcAPI.getAds: $error $stacktrace");
}
return null;
}
static Future<List<Release>?> getReleases() async {
try {
http.Response res = await http.get(Uri.parse(releases));

View File

@@ -101,7 +101,7 @@ Future loginAPI({
Provider.of<UserProvider>(context, listen: false).setUser(user.id);
// Get user data
// try {
try {
await Future.wait([
Provider.of<GradeProvider>(context, listen: false).fetch(),
Provider.of<TimetableProvider>(context, listen: false)
@@ -113,9 +113,9 @@ Future loginAPI({
Provider.of<EventProvider>(context, listen: false).fetch(),
Provider.of<AbsenceProvider>(context, listen: false).fetch(),
]);
// } catch (error) {
// print("WARNING: failed to fetch user data: $error");
// }
} catch (error) {
print("WARNING: failed to fetch user data: $error");
}
if (onSuccess != null) onSuccess();

View File

@@ -0,0 +1,29 @@
import 'package:filcnaplo/api/client.dart';
import 'package:filcnaplo/models/ad.dart';
import 'package:flutter/material.dart';
class AdProvider extends ChangeNotifier {
// private
late List<Ad> _ads;
bool get available => _ads.isNotEmpty;
// public
List<Ad> get ads => _ads;
AdProvider({
List<Ad> initialAds = const [],
required BuildContext context,
}) {
_ads = List.castFrom(initialAds);
}
Future<void> fetch() async {
_ads = await FilcAPI.getAds() ?? [];
_ads.sort((a, b) => -a.date.compareTo(b.date));
// check for new ads
if (_ads.isNotEmpty) {
notifyListeners();
}
}
}

View File

@@ -3,6 +3,7 @@ import 'dart:math';
import 'package:dynamic_color/dynamic_color.dart';
import 'package:filcnaplo/api/client.dart';
import 'package:filcnaplo/api/providers/ad_provider.dart';
import 'package:filcnaplo/api/providers/live_card_provider.dart';
import 'package:filcnaplo/api/providers/news_provider.dart';
import 'package:filcnaplo/api/providers/database_provider.dart';
@@ -104,6 +105,8 @@ class App extends StatelessWidget {
create: (context) => NewsProvider(context: context)),
ChangeNotifierProvider<UpdateProvider>(
create: (context) => UpdateProvider(context: context)),
ChangeNotifierProvider<AdProvider>(
create: (context) => AdProvider(context: context)),
// user data (kreten) providers
ChangeNotifierProvider<GradeProvider>(

View File

@@ -9,7 +9,7 @@ import 'package:permission_handler/permission_handler.dart';
class StorageHelper {
static Future<bool> write(String path, Uint8List data) async {
try {
if (await Permission.storage.request().isGranted) {
if (await Permission.manageExternalStorage.request().isGranted) {
await File(path).writeAsBytes(data);
return true;
} else {
@@ -34,5 +34,6 @@ class StorageHelper {
}
return downloads;
// return (await getTemporaryDirectory()).path;
}
}

View File

@@ -33,10 +33,10 @@ extension UpdateHelper on Release {
updateCallback(-1, UpdateState.installing);
var permStatus =
var installPerms =
(await Permission.manageExternalStorage.request().isGranted &&
await Permission.requestInstallPackages.request().isGranted);
if (permStatus) {
if (installPerms) {
var result = await OpenFile.open(apk.path);
if (result.type != ResultType.done) {

View File

@@ -0,0 +1,38 @@
class Ad {
String title;
String description;
String author;
Uri? logoUrl;
bool overridePremium;
DateTime date;
DateTime expireDate;
Uri launchUrl;
Ad({
required this.title,
required this.description,
required this.author,
this.logoUrl,
this.overridePremium = false,
required this.date,
required this.expireDate,
required this.launchUrl,
});
factory Ad.fromJson(Map json) {
print(json);
return Ad(
title: json['title'] ?? 'Ad',
description: json['description'] ?? '',
author: json['author'] ?? 'reFilc',
logoUrl: json['logo_url'] != null ? Uri.parse(json['logo_url']) : null,
overridePremium: json['override_premium'] ?? false,
date:
json['date'] != null ? DateTime.parse(json['date']) : DateTime.now(),
expireDate: json['expire_date'] != null
? DateTime.parse(json['expire_date'])
: DateTime.now(),
launchUrl: Uri.parse(json['launch_url'] ?? 'https://refilc.hu'),
);
}
}

View File

@@ -1,3 +1,4 @@
import 'package:filcnaplo/api/providers/ad_provider.dart';
import 'package:filcnaplo/api/providers/update_provider.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/ui/date_widget.dart';
@@ -14,6 +15,7 @@ import 'package:filcnaplo/ui/filter/widgets/lessons.dart' as lesson_filter;
import 'package:filcnaplo/ui/filter/widgets/update.dart' as update_filter;
import 'package:filcnaplo/ui/filter/widgets/missed_exams.dart'
as missed_exam_filter;
import 'package:filcnaplo/ui/filter/widgets/ads.dart' as ad_filter;
import 'package:filcnaplo_kreta_api/models/week.dart';
import 'package:filcnaplo_kreta_api/providers/absence_provider.dart';
import 'package:filcnaplo_kreta_api/providers/event_provider.dart';
@@ -50,7 +52,8 @@ enum FilterType {
lessons,
updates,
certifications,
missedExams
missedExams,
ads,
}
Future<List<DateWidget>> getFilterWidgets(FilterType activeData,
@@ -65,6 +68,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData,
final eventProvider = Provider.of<EventProvider>(context);
final updateProvider = Provider.of<UpdateProvider>(context);
final settingsProvider = Provider.of<SettingsProvider>(context);
final adProvider = Provider.of<AdProvider>(context);
List<DateWidget> items = [];
@@ -82,6 +86,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData,
getFilterWidgets(FilterType.updates, context: context),
getFilterWidgets(FilterType.certifications, context: context),
getFilterWidgets(FilterType.missedExams, context: context),
getFilterWidgets(FilterType.ads, context: context),
]);
items = all.expand((x) => x).toList();
@@ -89,7 +94,7 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData,
// Grades
case FilterType.grades:
if(!settingsProvider.gradeOpeningFun) {
if (!settingsProvider.gradeOpeningFun) {
gradeProvider.seenAll();
}
items = grade_filter.getWidgets(
@@ -164,6 +169,13 @@ Future<List<DateWidget>> getFilterWidgets(FilterType activeData,
items = missed_exam_filter
.getWidgets(timetableProvider.getWeek(Week.current()) ?? []);
break;
// Ads
case FilterType.ads:
if (adProvider.available) {
items = ad_filter.getWidgets(adProvider.ads);
}
break;
}
return items;
}

View File

@@ -0,0 +1,25 @@
import 'package:filcnaplo/models/ad.dart';
import 'package:filcnaplo/ui/date_widget.dart';
import 'package:filcnaplo_mobile_ui/common/widgets/ad/ad_viewable.dart'
as mobile;
List<DateWidget> getWidgets(List<Ad> providerAds) {
List<DateWidget> items = [];
if (providerAds.isNotEmpty) {
for (var ad in providerAds) {
if (ad.date.isBefore(DateTime.now()) &&
ad.expireDate.isAfter(DateTime.now())) {
providerAds.sort((a, b) => -a.date.compareTo(b.date));
items.add(DateWidget(
key: ad.description,
date: ad.date,
widget: mobile.AdViewable(ad),
));
}
}
}
return items;
}

View File

@@ -3,7 +3,7 @@ description: "Nem hivatalos e-napló alkalmazás az e-Kréta rendszerhez"
homepage: https://refilc.hu
publish_to: "none"
version: 4.2.1+221
version: 4.2.2+222
environment:
sdk: ">=2.17.0 <3.0.0"

View File

@@ -24,6 +24,11 @@ class KretaAPI {
KretaApiEndpoints.groupAverages +
"?oktatasiNevelesiFeladatUid=" +
uid;
static String averages(String iss, String uid) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.averages +
"?oktatasiNevelesiFeladatUid=" +
uid;
static String timetable(String iss, {DateTime? start, DateTime? end}) =>
BaseKreta.kreta(iss) +
KretaApiEndpoints.timetable +
@@ -90,6 +95,7 @@ class KretaApiEndpoints {
static const groups = "/ellenorzo/V3/Sajat/OsztalyCsoportok";
static const groupAverages =
"/ellenorzo/V3/Sajat/Ertekelesek/Atlagok/OsztalyAtlagok";
static const averages = "/ellenorzo/V3/idk";
static const timetable = "/ellenorzo/V3/Sajat/OrarendElemek";
static const exams = "/ellenorzo/V3/Sajat/BejelentettSzamonkeresek";
static const homework = "/ellenorzo/V3/Sajat/HaziFeladatok";

View File

@@ -73,8 +73,16 @@ class HomeworkProvider with ChangeNotifier {
if (user == null) throw "Cannot fetch Homework for User null";
String iss = user.instituteCode;
List? homeworkJson = await Provider.of<KretaClient>(_context, listen: false)
List? homeworkJson = [];
try {
homeworkJson = await Provider.of<KretaClient>(_context, listen: false)
.getAPI(KretaAPI.homework(iss, start: from));
} catch (e) {
// error fetcing homework (unknown error)
}
if (homeworkJson == null) throw "Cannot fetch Homework for User ${user.id}";
List<Homework> homework = [];

View File

@@ -0,0 +1,53 @@
import 'package:filcnaplo/models/ad.dart';
import 'package:filcnaplo/theme/colors/colors.dart';
import 'package:flutter/material.dart';
import 'package:filcnaplo_mobile_ui/common/panel/panel_button.dart';
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
class AdTile extends StatelessWidget {
const AdTile(this.ad, {Key? key, this.onTap, this.padding}) : super(key: key);
final Ad ad;
final Function()? onTap;
final EdgeInsetsGeometry? padding;
@override
Widget build(BuildContext context) {
print('geic');
print(ad);
return Padding(
padding: padding ?? const EdgeInsets.symmetric(horizontal: 8.0),
child: PanelButton(
padding: const EdgeInsets.only(left: 8.0, right: 16.0),
onPressed: onTap,
title: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
ad.title,
),
Text(
ad.description,
style: TextStyle(
fontWeight: FontWeight.w500,
color: AppColors.of(context).text.withOpacity(0.7),
),
),
],
),
leading: ad.logoUrl != null
? Image.network(
ad.logoUrl.toString(),
errorBuilder: (context, error, stackTrace) {
ad.logoUrl = null;
return const SizedBox();
},
)
: null,
trailing: const Icon(FeatherIcons.externalLink),
),
);
}
}

View File

@@ -0,0 +1,22 @@
import 'package:filcnaplo/models/ad.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import 'ad_tile.dart';
class AdViewable extends StatelessWidget {
const AdViewable(this.ad, {Key? key}) : super(key: key);
final Ad ad;
@override
Widget build(BuildContext context) {
return AdTile(
ad,
onTap: () => launchUrl(
ad.launchUrl,
mode: LaunchMode.externalApplication,
),
);
}
}

View File

@@ -18,7 +18,8 @@ class UpdateView extends StatefulWidget {
final Release release;
static void show(Release release, {required BuildContext context}) => showBottomCard(context: context, child: UpdateView(release));
static void show(Release release, {required BuildContext context}) =>
showBottomCard(context: context, child: UpdateView(release));
@override
_UpdateViewState createState() => _UpdateViewState();
@@ -45,7 +46,8 @@ class _UpdateViewState extends State<UpdateView> {
children: [
Text(
"new_update".i18n,
style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 18.0),
style: const TextStyle(
fontWeight: FontWeight.w700, fontSize: 18.0),
),
Text(
"${widget.release.version}",
@@ -75,7 +77,7 @@ class _UpdateViewState extends State<UpdateView> {
borderRadius: BorderRadius.circular(12.0),
),
child: SizedBox(
height: 125.0,
height: 200.0,
child: Markdown(
padding: const EdgeInsets.symmetric(horizontal: 12.0),
physics: const BouncingScrollPhysics(),
@@ -91,21 +93,30 @@ class _UpdateViewState extends State<UpdateView> {
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (state == UpdateState.downloading || state == UpdateState.preparing)
if (state == UpdateState.downloading ||
state == UpdateState.preparing)
Container(
height: 18.0,
width: 18.0,
margin: const EdgeInsets.only(right: 8.0),
child: CircularProgressIndicator(
value: progress > 0.05 ? progress : null,
color: ColorUtils.foregroundColor(AppColors.of(context).filc),
color: ColorUtils.foregroundColor(
AppColors.of(context).filc),
),
),
Text(["download".i18n, "downloading".i18n, "downloading".i18n, "installing".i18n][state.index].toUpperCase()),
Text([
"download".i18n,
"downloading".i18n,
"downloading".i18n,
"installing".i18n
][state.index]
.toUpperCase()),
],
),
backgroundColor: AppColors.of(context).filc,
onPressed: state == UpdateState.none ? () => downloadPrecheck() : null,
onPressed:
state == UpdateState.none ? () => downloadPrecheck() : null,
),
),
],
@@ -113,7 +124,8 @@ class _UpdateViewState extends State<UpdateView> {
);
}
String fmtSize() => "${(widget.release.downloads.first.size / 1024 / 1024).toStringAsFixed(1)} MB";
String fmtSize() =>
"${(widget.release.downloads.first.size / 1024 / 1024).toStringAsFixed(1)} MB";
void downloadPrecheck() {
final status = Provider.of<StatusProvider>(context, listen: false);
@@ -157,6 +169,7 @@ class _UpdateViewState extends State<UpdateView> {
.then((_) => Navigator.of(context).maybePop())
.catchError((error, stackTrace) {
if (mounted) {
Navigator.of(context).maybePop();
ScaffoldMessenger.of(context).showSnackBar(CustomSnackBar(
context: context,
content: Text("error".i18n),

View File

@@ -5,6 +5,8 @@ import 'package:filcnaplo/api/providers/database_provider.dart';
import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/models/settings.dart';
import 'package:filcnaplo/utils/format.dart';
// import 'package:filcnaplo_kreta_api/client/api.dart';
// import 'package:filcnaplo_kreta_api/client/client.dart';
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
import 'package:filcnaplo/helpers/average_helper.dart';
import 'package:filcnaplo/helpers/subject.dart';

View File

@@ -2,6 +2,8 @@ import 'dart:math';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:filcnaplo/api/providers/update_provider.dart';
// import 'package:filcnaplo_kreta_api/client/api.dart';
// import 'package:filcnaplo_kreta_api/client/client.dart';
import 'package:filcnaplo_kreta_api/providers/grade_provider.dart';
import 'package:filcnaplo/api/providers/user_provider.dart';
import 'package:filcnaplo/theme/colors/colors.dart';
@@ -112,6 +114,18 @@ class _GradesPageState extends State<GradesPage> {
} else {
tiles.insert(
0,
// TextButton(
// onPressed: () async {
// var url = KretaAPI.averages(
// user.instituteCode!,
// user.id!,
// );
// print(url);
// var res = await Provider.of<KretaClient>(context, listen: false)
// .getAPI(url);
// print(res);
// },
// child: Text('test')),
Padding(
padding: const EdgeInsets.only(top: 24.0),
child: Empty(subtitle: "empty".i18n),

View File

@@ -26,6 +26,7 @@ import 'package:home_widget/home_widget.dart';
import 'package:wtf_sliding_sheet/wtf_sliding_sheet.dart';
import 'package:background_fetch/background_fetch.dart';
import 'package:filcnaplo_premium/providers/goal_provider.dart';
import 'package:filcnaplo/api/providers/ad_provider.dart';
class NavigationScreen extends StatefulWidget {
const NavigationScreen({Key? key}) : super(key: key);
@@ -48,6 +49,7 @@ class NavigationScreenState extends State<NavigationScreen>
late GoalProvider goalProvider;
late UpdateProvider updateProvider;
late GradeProvider gradeProvicer;
late AdProvider adProvider;
NavigatorState? get navigator => _navigatorState.currentState;
@@ -176,6 +178,10 @@ class NavigationScreenState extends State<NavigationScreen>
updateProvider = Provider.of<UpdateProvider>(context, listen: false);
updateProvider.fetch();
// get advertisements
adProvider = Provider.of<AdProvider>(context, listen: false);
adProvider.fetch();
// initial sync
syncAll(context);
setupQuickActions();