Skip to content

Commit

Permalink
UI updated
Browse files Browse the repository at this point in the history
Application redesigned and base code changed. But it should refactor.
  • Loading branch information
mkaramuk committed Oct 24, 2023
1 parent 44b3540 commit 80124d0
Show file tree
Hide file tree
Showing 165 changed files with 618 additions and 366 deletions.
Empty file modified .gitignore
100644 → 100755
Empty file.
Empty file modified .metadata
100644 → 100755
Empty file.
Empty file modified LICENSE
100644 → 100755
Empty file.
6 changes: 2 additions & 4 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
# Asal

![Asal beta](screenshots/ss1.png)

Asal (Asal means honey in Arabic), is a Flutter application that aims to show and follow up pray times easily. It has a simple and plain UI and it's easy to use.
Asal, is a Flutter application that aims to show and follow up pray times easily.

## Compile

I think you don't need something else. You can compile and run the source code by typing `flutter run` on the terminal. If you encounter an error, please open an issue.
You can compile and run the source code by typing `flutter run` on the terminal. If you encounter an error, please open an issue.
Empty file modified analysis_options.yaml
100644 → 100755
Empty file.
Empty file modified android/.gitignore
100644 → 100755
Empty file.
Empty file modified android/app/build.gradle
100644 → 100755
Empty file.
Empty file modified android/app/src/debug/AndroidManifest.xml
100644 → 100755
Empty file.
59 changes: 30 additions & 29 deletions android/app/src/main/AndroidManifest.xml
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,34 +1,35 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.asal">
<application
android:label="asal"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
package="com.example.asal">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:label="Asal"
android:name="${applicationName}"
android:icon="@mipmap/launcher_icon">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
Empty file modified android/app/src/main/kotlin/com/example/asel/MainActivity.kt
100644 → 100755
Empty file.
Empty file modified android/app/src/main/res/drawable-v21/launch_background.xml
100644 → 100755
Empty file.
Empty file modified android/app/src/main/res/drawable/launch_background.xml
100644 → 100755
Empty file.
Empty file modified android/app/src/main/res/mipmap-hdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified android/app/src/main/res/mipmap-mdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified android/app/src/main/res/values-night/styles.xml
100644 → 100755
Empty file.
Empty file modified android/app/src/main/res/values/styles.xml
100644 → 100755
Empty file.
Empty file modified android/app/src/profile/AndroidManifest.xml
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion android/build.gradle
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ subprojects {
project.evaluationDependsOn(':app')
}

task clean(type: Delete) {
tasks.register("clean", Delete) {
delete rootProject.buildDir
}
Empty file modified android/gradle.properties
100644 → 100755
Empty file.
Empty file modified android/gradle/wrapper/gradle-wrapper.properties
100644 → 100755
Empty file.
Empty file modified android/settings.gradle
100644 → 100755
Empty file.
Binary file added assets/google_fonts/RobotoCondensed-Bold.ttf
Binary file not shown.
Binary file not shown.
Binary file added assets/google_fonts/RobotoCondensed-Italic.ttf
Binary file not shown.
Binary file added assets/google_fonts/RobotoCondensed-Light.ttf
Binary file not shown.
Binary file not shown.
Binary file added assets/google_fonts/RobotoCondensed-Regular.ttf
Binary file not shown.
Binary file added assets/icons/icon.ico
Binary file not shown.
Binary file added assets/icons/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified assets/images/background.jpg
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/evening.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/morning.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/night.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/noon.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file modified ios/.gitignore
100644 → 100755
Empty file.
Empty file modified ios/Flutter/AppFrameworkInfo.plist
100644 → 100755
Empty file.
Empty file modified ios/Flutter/Debug.xcconfig
100644 → 100755
Empty file.
Empty file modified ios/Flutter/Release.xcconfig
100644 → 100755
Empty file.
Empty file modified ios/Runner.xcodeproj/project.pbxproj
100644 → 100755
Empty file.
Empty file.
Empty file.
Empty file.
Empty file modified ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
100644 → 100755
Empty file.
Empty file modified ios/Runner.xcworkspace/contents.xcworkspacedata
100644 → 100755
Empty file.
Empty file modified ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
100644 → 100755
Empty file.
Empty file.
Empty file modified ios/Runner/AppDelegate.swift
100644 → 100755
Empty file.
Empty file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
100644 → 100755
Empty file.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Binary file modified ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected]
100644 → 100755
Empty file modified ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
100644 → 100755
Empty file.
Empty file modified ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
100644 → 100755
Empty file modified ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
100644 → 100755
Empty file.
Empty file modified ios/Runner/Base.lproj/LaunchScreen.storyboard
100644 → 100755
Empty file.
Empty file modified ios/Runner/Base.lproj/Main.storyboard
100644 → 100755
Empty file.
Empty file modified ios/Runner/Info.plist
100644 → 100755
Empty file.
Empty file modified ios/Runner/Runner-Bridging-Header.h
100644 → 100755
Empty file.
Empty file modified lib/dialogs/update_times/update_times_cubit.dart
100644 → 100755
Empty file.
Empty file modified lib/dialogs/update_times/update_times_view.dart
100644 → 100755
Empty file.
16 changes: 16 additions & 0 deletions lib/extensions/date_extensions.dart
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,20 @@ extension DateExtensions on DateTime {
bool isBetween(DateTime a, DateTime b) {
return isAfter(a) && isBefore(b);
}

get timeInSeconds {
return (hour * 60 * 60) + (minute * 60) + second;
}

String toDifferenceString(DateTime b) {
if (b.timeInSeconds < timeInSeconds) {
b = b.add(const Duration(days: 1));
}
Duration diff = difference(b);
String hours = diff.inHours.abs().toString().padLeft(2, '0');
String minutes = (diff.inMinutes - (diff.inHours * 60)).abs().toString().padLeft(2, '0');
String seconds = (diff.inSeconds - diff.inMinutes * 60).abs().toString().padLeft(2, '0');

return "$hours:$minutes:$seconds";
}
}
11 changes: 10 additions & 1 deletion lib/main.dart
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@ import 'dart:io';
import 'package:asal/router/routes.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:window_manager/window_manager.dart';

Future<void> main() async {
GoogleFonts.config.allowRuntimeFetching = false;
WidgetsFlutterBinding.ensureInitialized();
EasyLoading.instance.userInteractions = false;

if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
windowManager.setTitle("Asal");
windowManager.setMaximumSize(const Size(300, 700));
windowManager.setMaximumSize(const Size(400, 700));
windowManager.setMinimumSize(const Size(400, 700));

if (Platform.isWindows) {
windowManager.setIcon("assets/icons/icon.ico");
} else {
windowManager.setIcon("assets/icons/icon.png");
}
}

runApp(const AsalApp());
Expand Down
6 changes: 3 additions & 3 deletions lib/models/calendar_model.dart
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class CalendarModel {
DayModel today() {
DateTime now = DateTime.now();
return days.firstWhere((element) {
return element.date.day == now.day &&
element.date.month == now.month &&
element.date.year == now.year;
return element.date.value.day == now.day &&
element.date.value.month == now.month &&
element.date.value.year == now.year;
});
}
}
55 changes: 30 additions & 25 deletions lib/models/day_model.dart
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:asal/models/time_model.dart';
import 'package:intl/intl.dart';

String _parseTime(String time) {
Expand All @@ -13,36 +14,40 @@ DateTime _parseWithDate(String time) {
}

class DayModel {
final DateTime date;
final DateTime fajr;
final DateTime sunrise;
final DateTime dhuhr;
final DateTime asr;
final DateTime maghrib;
final DateTime isha;

DayModel(this.date, this.fajr, this.sunrise, this.dhuhr, this.asr, this.maghrib, this.isha);

DayModel.fromJson(Map<String, dynamic> json)
: date = DateFormat("dd-MM-yyyy").parse(json["date"]["gregorian"]["date"]),
fajr = _parseWithDate(_parseTime(json["timings"]["Fajr"])),
sunrise = _parseWithDate(_parseTime(json["timings"]["Sunrise"])),
dhuhr = _parseWithDate(_parseTime(json["timings"]["Dhuhr"])),
asr = _parseWithDate(_parseTime(json["timings"]["Asr"])),
maghrib = _parseWithDate(_parseTime(json["timings"]["Maghrib"])),
isha = _parseWithDate(_parseTime(json["timings"]["Isha"]));
final TimeModel date = TimeModel(DateTime.now(), "Tarih");
final TimeModel fajr = TimeModel(DateTime.now(), "İmsak", image: "assets/images/evening.jpg");
final TimeModel sunrise = TimeModel(DateTime.now(), "Güneş", image: "assets/images/morning.jpg");
final TimeModel dhuhr = TimeModel(DateTime.now(), "Öğle", image: "assets/images/noon.jpg");
final TimeModel asr = TimeModel(DateTime.now(), "İkindi", image: "assets/images/morning.jpg");
final TimeModel maghrib = TimeModel(DateTime.now(), "Akşam", image: "assets/images/evening.jpg");
final TimeModel isha = TimeModel(DateTime.now(), "Yatsı", image: "assets/images/night.jpg");

DayModel();

factory DayModel.fromJson(Map<String, dynamic> json) {
DayModel day = DayModel();

day.date.value = DateFormat("dd-MM-yyyy").parse(json["date"]["gregorian"]["date"]);
day.fajr.value = _parseWithDate(_parseTime(json["timings"]["Fajr"]));
day.sunrise.value = _parseWithDate(_parseTime(json["timings"]["Sunrise"]));
day.dhuhr.value = _parseWithDate(_parseTime(json["timings"]["Dhuhr"]));
day.asr.value = _parseWithDate(_parseTime(json["timings"]["Asr"]));
day.maghrib.value = _parseWithDate(_parseTime(json["timings"]["Maghrib"]));
day.isha.value = _parseWithDate(_parseTime(json["timings"]["Isha"]));
return day;
}

Map<String, dynamic> toJson() => {
"date": {
"gregorian": {"date": DateFormat("dd-MM-yyyy").format(date)}
"gregorian": {"date": DateFormat("dd-MM-yyyy").format(date.value)}
},
"timings": {
"Fajr": _timeFormat.format(fajr),
"Sunrise": _timeFormat.format(sunrise),
"Dhuhr": _timeFormat.format(dhuhr),
"Asr": _timeFormat.format(asr),
"Maghrib": _timeFormat.format(maghrib),
"Isha": _timeFormat.format(isha),
"Fajr": _timeFormat.format(fajr.value),
"Sunrise": _timeFormat.format(sunrise.value),
"Dhuhr": _timeFormat.format(dhuhr.value),
"Asr": _timeFormat.format(asr.value),
"Maghrib": _timeFormat.format(maghrib.value),
"Isha": _timeFormat.format(isha.value),
}
};
}
7 changes: 7 additions & 0 deletions lib/models/time_model.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class TimeModel {
final String name;
DateTime value;
String image = "";

TimeModel(this.value, this.name, {this.image = ""});
}
76 changes: 55 additions & 21 deletions lib/pages/homepage/homepage_cubit.dart
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ import 'package:asal/dialogs/update_times/update_times_view.dart';
import 'package:asal/extensions/date_extensions.dart';
import 'package:asal/models/calendar_model.dart';
import 'package:asal/models/day_model.dart';
import 'package:asal/models/time_model.dart';
import 'package:asal/services/config_service.dart';
import 'package:asal/services/praytimes_service.dart';
import 'package:carousel_slider/carousel_slider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:intl/intl.dart';

class HomepageCubit extends Cubit<HomepageState> {
HomepageCubit(this.context) : super(HomepageLoading()) {
_loadCalendar();
}
int cardIndex = 0;
int nextTimeIndex = 0;
TimeModel nextTime = TimeModel(DateTime.now(), "Vakit");
DayModel today = DayModel();
BuildContext context;
CalendarModel? calendar;
List<TimeModel> prayTimes = [];
CarouselController carouselController = CarouselController();
late Timer timer;
late TimeModel lastTime;

void onCardChanged(int index, CarouselPageChangedReason reason) {
cardIndex = index;
emit(HomepageLoaded());
}

Future<bool?> showUpdateTimesDialog() async {
return showDialog<bool>(context: context, builder: (context) => UpdateTimesDialog);
Expand All @@ -31,35 +43,57 @@ class HomepageCubit extends Cubit<HomepageState> {
} while (updated != null && !updated);
calendar = await ConfigService.loadCalendar();
}

today = calendar!.today();
findNextTime();
lastTime = nextTime;
cardIndex = nextTimeIndex;
emit(HomepageLoaded());

timer = Timer.periodic(const Duration(seconds: 1), (Timer _) {
checkToday();
findNextTime();
checkTimeChange();
emit(HomepageLoaded());
});
}

String get timeLeft {
Duration difference = nextTime.difference(DateTime.now());
String hours = difference.inHours.toString().padLeft(2, '0');
String minutes = (difference.inMinutes - (difference.inHours * 60)).toString().padLeft(2, '0');
String seconds = (difference.inSeconds - difference.inMinutes * 60).toString().padLeft(2, '0');
if (prayTimes.isEmpty) {
return "00:00:00";
}

return "$hours:$minutes:$seconds";
return DateTime.now().toDifferenceString(prayTimes[cardIndex].value);
}

DateTime get nextTime {
void checkTimeChange() {
if (lastTime.name != nextTime.name) {
lastTime = nextTime;
cardIndex = nextTimeIndex;
carouselController.animateToPage(cardIndex,
duration: const Duration(seconds: 1), curve: Curves.easeInOut);
}
}

void findNextTime() {
prayTimes = [today.fajr, today.sunrise, today.dhuhr, today.asr, today.maghrib, today.isha];
DateTime now = DateTime.now();
DayModel today = calendar!.today();
if (now.isBetween(today.fajr, today.sunrise)) {
return today.sunrise;
} else if (now.isBetween(today.sunrise, today.dhuhr)) {
return today.dhuhr;
} else if (now.isBetween(today.dhuhr, today.asr)) {
return today.asr;
} else if (now.isBetween(today.asr, today.maghrib)) {
return today.maghrib;
} else if (now.isBetween(today.maghrib, today.isha)) {
return today.isha;
} else /*if (now.isBetween(today.isha, today.fajr)) */ {
return today.fajr;

for (int i = 1; i < prayTimes.length; i++) {
if (now.isBetween(prayTimes[i - 1].value, prayTimes[i].value)) {
nextTime = prayTimes[i];
nextTimeIndex = i;
return;
}
}

nextTime = prayTimes[0];
nextTimeIndex = 0;
}

void checkToday() {
if (DateTime.now().day != today.date.value.day) {
today = calendar!.today();
}
}
}
Expand Down
Loading

0 comments on commit 80124d0

Please sign in to comment.