Giter Site home page Giter Site logo

alessioc42 / lanis-mobile Goto Github PK

View Code? Open in Web Editor NEW
31.0 4.0 0.0 79.97 MB

Unofficial app for the school portal Hessen by a group of high school students. By students. For students.

Home Page: https://alessioc42.github.io/lanis-mobile/

License: GNU General Public License v3.0

Dart 99.02% Kotlin 0.03% Java 0.18% Ruby 0.38% Swift 0.22% Objective-C 0.01% Shell 0.15%
schulportal-hessen vertretungsplan schule schule-infoportal sph android flutter reverse-engineering apk

lanis-mobile's Introduction

Lanis Mobile

Inoffizielle App rund um das Schulportal Hessen. Unterstützung für den Vertretungsplan, "Mein Unterricht", Nachrichten und den Schulkalender mit mehr Geplant.

Einsatz an über 50 Schulen in Hessen mit mehreren hundert Nutzern

Jetzt bei Google Play

Get it on IzzyOnDroid

Screenshots

Hilf mit!

Wir sind offen für neue Colaborator. Aber auch wenn du nicht coden kannst, bist du in der Lage einen beitrag zur App zu leisten. Du kannst den Vertretungsplan deiner Schule anpassen. Siehe hier und hier

features

  • Login
  • Vertretungsplan
  • Vertretungsplan Push benachrichtigungen (Android)
  • Schulkalender
  • Lanis eingeloggt im browser öffnen
  • Benutzerdaten
  • Mein Unterricht
  • Nachrichten
  • Datenspeicher
  • Stundenplan
  • Offline support?

Es werden anonyme Daten zur Fehleranalyse erhoben. (Optional)

IOS/IpadOS support

Die App ist zwar noch nicht im App Store, es kann jedoch eine .IPA Datei unter "releases" heruntergeladen und installiert werden. Dabei finden keine automatischen Updates statt.

iOS wurde bisher ausschließlich durch die Immanuel Kant Schule (5181) getestet.

Mitarbeit

Schulkonfiguration der Vertretungspläne

Dieses Projekt ist stark von Bug-Reports anderer Schulen oder von neuen Mitarbeitern abhängig. Der Grund dafür liegt in der modularen Natur des Schulportals, die es äußerst schwierig macht, eine universelle Lanis-App zu entwickeln.

Bug-Reports können auch an diese E-Mail-Adresse gesendet werden, falls kein Github-Konto vorhanden ist.

Countly - Product Analytics

lanis-mobile's People

Contributors

alessioc42 avatar codespoof avatar dependabot[bot] avatar izzysoft avatar kurwjan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

lanis-mobile's Issues

"Mein Unterricht" "Aktuelles" Lehrernamen Format

In "Aktuelles" bei "Mein Unterricht" wird das Namen Format: Kürzel-Nachname, Vorname genutzt.
In "Nachrichten" und "Kursmappen" wird bei "Mein Unterricht" wird das Namen Format: Nachname, Vorname ( Kürzel) genutzt.
Es wäre besser, wenn das Format immer gleich ist.

Kursmappe Crash

Wenn ich in "Mein Unterricht" eine bestimmte Kursmappe öffne, stürzt die App ab.
Error:

W/OnBackInvokedCallback(20478): OnBackInvokedCallback is not enabled for the application.
W/OnBackInvokedCallback(20478): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest.
D/EGL_emulation(20478): app_time_stats: avg=60.14ms min=2.63ms max=2251.43ms count=49

======== Exception caught by widgets library =======================================================
The following _TypeError was thrown building:
type 'Null' is not a subtype of type 'String'

When the exception was thrown, this was the stack: 
#0      _CourseOverviewAnsichtState._buildBody.<anonymous closure> (package:sph_plan/view/mein_unterricht/course_overview.dart:124:60)
#1      SliverChildBuilderDelegate.build (package:flutter/src/widgets/scroll_delegate.dart:490:22)
#2      SliverMultiBoxAdaptorElement._build (package:flutter/src/widgets/sliver.dart:829:28)
#3      SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:843:55)
#4      BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2835:19)
#5      SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:835:12)
#6      RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:349:23)
#7      RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:2657:59)
#8      PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1071:15)
#9      RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:2657:14)
#10     RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:338:5)
#11     RenderSliverMultiBoxAdaptor.addInitialChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:424:5)
#12     RenderSliverList.performLayout (package:flutter/src/rendering/sliver_list.dart:77:12)
#13     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#14     RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:139:12)
#15     RenderSliverPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:361:11)
#16     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#17     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:601:13)
#18     RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1554:12)
#19     RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1463:20)
#20     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#21     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#22     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#23     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#24     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#25     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#26     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#27     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#28     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#29     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#30     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#31     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#32     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#33     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#34     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#35     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#36     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#37     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#38     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#39     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#40     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#41     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#42     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#43     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#44     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1434:11)
#45     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#46     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#47     MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:173:12)
#48     _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1062:7)
#49     MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:237:7)
#50     RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:403:14)
#51     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#52     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#53     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#54     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#55     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#56     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#57     _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1434:11)
#58     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#59     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#60     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#61     RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2385:7)
#62     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1025:18)
#63     PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1038:15)
#64     RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:591:23)
#65     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:986:13)
#66     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#67     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#68     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#69     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
#70     _invoke (dart:ui/hooks.dart:312:13)
#71     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
#72     _drawFrame (dart:ui/hooks.dart:283:31)
====================================================================================================
D/EGL_emulation(20478): app_time_stats: avg=21.03ms min=3.46ms max=251.92ms count=48
W/FirebaseCrashlytics(20478): Unable to read App Quality Sessions session id.
D/CompatibilityChangeReporter(20478): Compat change id reported: 194532703; UID 10163; state: ENABLED
I/TRuntime.CctTransportBackend(20478): Making request to: https://crashlyticsreports-pa.googleapis.com/v1/firelog/legacy/batchlog
D/TrafficStats(20478): tagSocket(100) with statsTag=0xffffffff, statsUid=-1
I/TRuntime.CctTransportBackend(20478): Status Code: 200

Wenn man die Zeile (package:sph_plan/view/mein_unterricht/course_overview.dart:124:60) auskommentiert, funktioniert es ohne Probleme.

App Bug

Wenn ich mit meinem Account über die App anmelde hat es keine Probleme, aber danach ist nur noch Hellgrau zu sehen.
(Es könnte daran liegen, dass meine Schule keinen Vertretungsplan beim Schulportal hat.)
Die Version v2.8.0+8 hat den Bug aber die Version v2.7.0+7 hat ihn nicht.

Nachrichten in manchen Schulen keine Beta mehr

In unserer Schule ist das Nachrichten-Modul in der JSON nicht mehr Beta Version genannt und wird daher als unsupported markiert. Ist das in anderen Schulen noch anders oder kann man die Strings einfach ersetzen? Dann würde ich gleich ein PR machen. Sonst halt mit OR verknüpft.

JSON
{
  "error": "0",
  "folders": [
    {
      "name": "Start",
      "logo": "fa fa-newspaper-o",
      "farbe": "faebcc"
    },
    {
      "name": "Allgemein",
      "logo": "fa fa-folder-o",
      "farbe": "000000"
    },
    {
      "name": "Anleitungen und Fortbildungen",
      "logo": "fa fa-folder-o",
      "farbe": "000000"
    },
    {
      "name": "Organisation",
      "logo": "fa fa-folder-o",
      "farbe": "000000"
    },
    {
      "name": "Schule",
      "logo": "fa fa-folder-o",
      "farbe": "000000"
    },
    {
      "name": "Unterricht",
      "logo": "fa fa-folder-o",
      "farbe": "000000"
    }
  ],
  "entrys": [
    {
      "Name": "Abiturhelfer",
      "Farbe": "25599A",
      "Logo": "fas fa-marker",
      "Ordner": [
        "Organisation"
      ],
      "link": "abiturhelfer.php"
    },
    {
      "Name": "Bildungsserver Hessen",
      "Farbe": "203090",
      "Logo": "fa fa-cloud",
      "Ordner": [
        "Unterricht"
      ],
      "link": "index.php?a=f&e=t12-1",
      "target": "_blank"
    },
    {
      "Name": "Dateispeicher",
      "Farbe": "89c48a",
      "Logo": "fas fa-file-contract",
      "Ordner": [
        "Organisation"
      ],
      "link": "dateispeicher.php"
    },
    {
      "Name": "Dateiverteilung",
      "Farbe": "168647",
      "Logo": "fa fa-files-o",
      "Ordner": [
        "Organisation"
      ],
      "link": "dateiverteilung.php"
    },
    {
      "Name": "Homepage ASF",
      "Farbe": "1c3fb4",
      "Logo": "fa fa-cloud",
      "Ordner": [
        "Schule"
      ],
      "link": "index.php?a=f&e=l1",
      "target": "_blank"
    },
    {
      "Name": "Kalender",
      "Farbe": "168647",
      "Logo": "fa fa-calendar\r\n",
      "Ordner": [
        "Allgemein",
        "Start"
      ],
      "link": "kalender.php"
    },
    {
      "Name": "Lerngruppen",
      "Farbe": "5ec3d5",
      "Logo": "fa fa-users",
      "Ordner": [
        "Organisation"
      ],
      "link": "lerngruppen.php"
    },
    {
      "Name": "Lizenzfreie Bilder & Fotos",
      "Farbe": "57b057",
      "Logo": "fa fa-picture-o",
      "Ordner": [
        "Unterricht"
      ],
      "link": "index.php?a=f&e=t50-1"
    },
    {
      "Name": "Matheretter",
      "Farbe": "EBFBDB",
      "Logo": "fas fa-equals",
      "Ordner": [
        "Unterricht"
      ],
      "link": "index.php?a=f&e=t78-1"
    },
    {
      "Name": "mein Unterricht",
      "Farbe": "fc7520",
      "Logo": "fa fa-flip-horizontal fa-address-book ",
      "Ordner": [
        "Organisation"
      ],
      "link": "meinunterricht.php"
    },
    {
      "Name": "Nachrichten",
      "Farbe": "010149",
      "Logo": "fas fa-mail-bulk",
      "Ordner": [
        "Organisation"
      ],
      "link": "nachrichten.php"
    },
    {
      "Name": "Oberstufenkurswahl",
      "Farbe": "3175B0",
      "Logo": "fa fa-check-square-o\r\n",
      "Ordner": [
        "Organisation"
      ],
      "link": "oberstufenwahl.php"
    },
    {
      "Name": "Schulbildungsnetz des WTK",
      "Farbe": "a4ce2f",
      "Logo": "fa fa-archive",
      "Ordner": [
        "Schule"
      ],
      "link": "index.php?a=f&e=l2",
      "target": "_blank"
    },
    {
      "Name": "SchulMoodle",
      "Farbe": "#ff8c00",
      "Logo": "fa fa-align-justify",
      "Ordner": [
        "Unterricht"
      ],
      "link": "schulmoodle.php",
      "target": "_blank"
    },
    {
      "Name": "Select",
      "Farbe": "394e03",
      "Logo": "fa fa-check-circle-o",
      "Ordner": [
        "Unterricht"
      ],
      "link": "index.php?a=f&e=t25-1",
      "target": "_blank"
    },
    {
      "Name": "SPH-Kurzanleitungen",
      "Farbe": "00BCD4",
      "Logo": "far fa-smile",
      "Ordner": [
        "Anleitungen und Fortbildungen"
      ],
      "link": "usesheets.php"
    },
    {
      "Name": "Stundenplan",
      "Farbe": "010149",
      "Logo": "fa fa-hourglass-half",
      "Ordner": [
        "Allgemein",
        "Start"
      ],
      "link": "stundenplan.php"
    },
    {
      "Name": "Vertretungsplan",
      "Farbe": "168647",
      "Logo": "fa fa-book",
      "Ordner": [
        "Allgemein"
      ],
      "link": "vertretungsplan.php"
    },
    {
      "Name": "Videokonferenz",
      "Farbe": "010172",
      "Logo": "fa fa-video",
      "Ordner": [
        "Organisation"
      ],
      "link": "videokonferenz.php",
      "target": "_blank"
    }
  ],
  "till": 1705422361
}

Widget overflow on large system scaling

Wenn man auf einem Gerät mit einer Großen Schriftgröße die App nutzt kann es sein, dass sich das Datum verschiebt, wenn der Lehrer einen zu langen Namen hat.
WhatsApp Image 2024-01-19 at 22 32 42_4e5b86cf

Auto re-login option

Dem Nutzer Erlauben, selber zu entscheiden, ob das Passwort auf dem Eigenen gerät gespeichert werden soll.

Kalender Crash

Wenn die Kalender Seite geöffnet wird, stützt die App ab.
Error:

D/EGL_emulation( 7842): app_time_stats: avg=341.57ms min=4.20ms max=9055.48ms count=28

======== Exception caught by widgets library =======================================================
The following LocaleDataException was thrown building CalendarHeader(dirty):
Locale data has not been initialized, call initializeDateFormatting(<locale>).

The relevant error-causing widget was: 
  TableCalendar<Event> TableCalendar:file:///C:/Users/user/StudioProjects/lanis-mobile/app/lib/view/calendar/calendar.dart:472:15
When the exception was thrown, this was the stack: 
#0      UninitializedLocaleData._throwException (package:intl/src/intl_helpers.dart:81:5)
#1      UninitializedLocaleData.containsKey (package:intl/src/intl_helpers.dart:75:7)
#2      DateFormat.localeExists (package:intl/src/intl/date_format.dart:824:28)
#3      verifiedLocale (package:intl/src/intl_helpers.dart:186:19)
#4      new DateFormat (package:intl/src/intl/date_format.dart:267:27)
#5      new DateFormat.yMMMM (package:intl/src/intl/date_format.dart:472:32)
#6      CalendarHeader.build (package:table_calendar/src/widgets/calendar_header.dart:43:20)
#7      StatelessElement.build (package:flutter/src/widgets/framework.dart:5541:49)
#8      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#9      Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#10     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5453:5)
#11     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5447:5)
...     Normal element mounting (9 frames)
#20     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#21     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#22     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
...     Normal element mounting (9 frames)
#31     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#32     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6871:36)
#33     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/framework.dart:6883:32)
#34     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#35     Element.updateChild (package:flutter/src/widgets/framework.dart:3831:20)
#36     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5496:16)
#37     StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:5634:11)
#38     Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#39     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2895:19)
#40     WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:984:21)
#41     RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#42     SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#43     SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#44     SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
#45     _invoke (dart:ui/hooks.dart:312:13)
#46     PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
#47     _drawFrame (dart:ui/hooks.dart:283:31)
====================================================================================================

======== Exception caught by widgets library =======================================================
The following LocaleDataException was thrown building CalendarPage(dirty):
Locale data has not been initialized, call initializeDateFormatting(<locale>).

The relevant error-causing widget was: 
  TableCalendar<Event> TableCalendar:file:///C:/Users/user/StudioProjects/lanis-mobile/app/lib/view/calendar/calendar.dart:472:15
When the exception was thrown, this was the stack: 
#0      UninitializedLocaleData._throwException (package:intl/src/intl_helpers.dart:81:5)
#1      UninitializedLocaleData.containsKey (package:intl/src/intl_helpers.dart:75:7)
#2      DateFormat.localeExists (package:intl/src/intl/date_format.dart:824:28)
#3      verifiedLocale (package:intl/src/intl_helpers.dart:186:19)
#4      new DateFormat (package:intl/src/intl/date_format.dart:267:27)
#5      new DateFormat.E (package:intl/src/intl/date_format.dart:450:28)
#6      _TableCalendarState.build.<anonymous closure> (package:table_calendar/src/table_calendar.dart:539:32)
#7      CalendarCore.build.<anonymous closure>.<anonymous closure> (package:table_calendar/src/widgets/calendar_core.dart:90:34)
#8      CalendarPage._buildDaysOfWeek.<anonymous closure> (package:table_calendar/src/widgets/calendar_page.dart:78:31)
#9      new _GrowableList.generate (dart:core-patch/growable_array.dart:136:28)
#10     CalendarPage._buildDaysOfWeek (package:table_calendar/src/widgets/calendar_page.dart:76:22)
#11     CalendarPage.build (package:table_calendar/src/widgets/calendar_page.dart:48:33)
#12     StatelessElement.build (package:flutter/src/widgets/framework.dart:5541:49)
#13     ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5471:15)
#14     Element.rebuild (package:flutter/src/widgets/framework.dart:5187:7)
#15     ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5453:5)
#16     ComponentElement.mount (package:flutter/src/widgets/framework.dart:5447:5)
...     Normal element mounting (41 frames)
#57     Element.inflateWidget (package:flutter/src/widgets/framework.dart:4326:16)
#58     Element.updateChild (package:flutter/src/widgets/framework.dart:3837:18)
#59     SliverMultiBoxAdaptorElement.updateChild (package:flutter/src/widgets/sliver.dart:858:37)
#60     SliverMultiBoxAdaptorElement.createChild.<anonymous closure> (package:flutter/src/widgets/sliver.dart:843:20)
#61     BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2835:19)
#62     SliverMultiBoxAdaptorElement.createChild (package:flutter/src/widgets/sliver.dart:835:12)
#63     RenderSliverMultiBoxAdaptor._createOrObtainChild.<anonymous closure> (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:349:23)
#64     RenderObject.invokeLayoutCallback.<anonymous closure> (package:flutter/src/rendering/object.dart:2657:59)
#65     PipelineOwner._enableMutationsToDirtySubtrees (package:flutter/src/rendering/object.dart:1071:15)
#66     RenderObject.invokeLayoutCallback (package:flutter/src/rendering/object.dart:2657:14)
#67     RenderSliverMultiBoxAdaptor._createOrObtainChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:338:5)
#68     RenderSliverMultiBoxAdaptor.addInitialChild (package:flutter/src/rendering/sliver_multi_box_adaptor.dart:424:5)
#69     RenderSliverFixedExtentBoxAdaptor.performLayout (package:flutter/src/rendering/sliver_fixed_extent_list.dart:274:12)
#70     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#71     RenderSliverEdgeInsetsPadding.performLayout (package:flutter/src/rendering/sliver_padding.dart:139:12)
#72     _RenderSliverFractionalPadding.performLayout (package:flutter/src/widgets/sliver_fill.dart:160:11)
#73     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#74     RenderViewportBase.layoutChildSequence (package:flutter/src/rendering/viewport.dart:601:13)
#75     RenderViewport._attemptLayout (package:flutter/src/rendering/viewport.dart:1554:12)
#76     RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:1463:20)
#77     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#78     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#79     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#80     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#81     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#82     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#83     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#84     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#85     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#86     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#87     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#88     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#89     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#90     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#91     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#92     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#93     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#94     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#95     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#96     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#97     RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#98     RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#99     RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#100    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#101    _RenderCustomClip.performLayout (package:flutter/src/rendering/proxy_box.dart:1434:11)
#102    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#103    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#104    RenderConstrainedBox.performLayout (package:flutter/src/rendering/proxy_box.dart:279:14)
#105    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#106    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#107    RenderAnimatedSize.performLayout (package:flutter/src/rendering/animated_size.dart:244:12)
#108    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#109    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#110    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#111    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#112    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#113    RenderProxyBoxMixin.performLayout (package:flutter/src/rendering/proxy_box.dart:104:21)
#114    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#115    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#116    _RenderLayoutBuilder.performLayout (package:flutter/src/widgets/layout_builder.dart:310:14)
#117    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#118    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#119    ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:52:11)
#120    RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:808:43)
#121    RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:903:32)
#122    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#123    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#124    ChildLayoutHelper.layoutChild (package:flutter/src/rendering/layout_helper.dart:52:11)
#125    RenderFlex._computeSizes (package:flutter/src/rendering/flex.dart:808:43)
#126    RenderFlex.performLayout (package:flutter/src/rendering/flex.dart:903:32)
#127    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#128    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#129    RenderPositionedBox.performLayout (package:flutter/src/rendering/shifted_box.dart:434:14)
#130    RenderObject.layout (package:flutter/src/rendering/object.dart:2546:7)
#131    RenderBox.layout (package:flutter/src/rendering/box.dart:2389:11)
#132    MultiChildLayoutDelegate.layoutChild (package:flutter/src/rendering/custom_layout.dart:173:12)
#133    _ScaffoldLayout.performLayout (package:flutter/src/material/scaffold.dart:1062:7)
#134    MultiChildLayoutDelegate._callPerformLayout (package:flutter/src/rendering/custom_layout.dart:237:7)
#135    RenderCustomMultiChildLayoutBox.performLayout (package:flutter/src/rendering/custom_layout.dart:403:14)
#136    RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:2385:7)
#137    PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1025:18)
#138    PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1038:15)
#139    RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:591:23)
#140    WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:986:13)
#141    RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:457:5)
#142    SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1325:15)
#143    SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1255:9)
#144    SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:1113:5)
#145    _invoke (dart:ui/hooks.dart:312:13)
#146    PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:383:5)
#147    _drawFrame (dart:ui/hooks.dart:283:31)
====================================================================================================
W/FirebaseCrashlytics( 7842): Unable to read App Quality Sessions session id.

======== Exception caught by rendering library =====================================================
The following assertion was thrown during layout:
A RenderFlex overflowed by 99577 pixels on the bottom.

The relevant error-causing widget was: 
  Column Column:file:///C:/Users/user/StudioProjects/lanis-mobile/app/lib/view/calendar/calendar.dart:470:18
The overflowing RenderFlex has an orientation of Axis.vertical.
The edge of the RenderFlex that is overflowing has been marked in the rendering with a yellow and black striped pattern. This is usually caused by the contents being too big for the RenderFlex.

Consider applying a flex factor (e.g. using an Expanded widget) to force the children of the RenderFlex to fit within the available space instead of being sized to their natural size.
This is considered an error condition because it indicates that there is content that cannot be seen. If the content is legitimately bigger than the available space, consider clipping it with a ClipRect widget before putting it in the flex, or using a scrollable container rather than a Flex, like a ListView.

The specific RenderFlex in question is: RenderFlex#e8cb3 relayoutBoundary=up2 OVERFLOWING
...  needs compositing
...  parentData: offset=Offset(0.0, 0.0) (can use size)
...  constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=707.4)
...  size: Size(411.4, 707.4)
...  direction: vertical
...  mainAxisAlignment: start
...  mainAxisSize: max
...  crossAxisAlignment: center
...  verticalDirection: down
◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤◢◤
====================================================================================================
W/FirebaseCrashlytics( 7842): Unable to read App Quality Sessions session id.
W/FirebaseCrashlytics( 7842): Unable to read App Quality Sessions session id.
I/TRuntime.CctTransportBackend( 7842): Making request to: https://crashlyticsreports-pa.googleapis.com/v1/firelog/legacy/batchlog
I/TRuntime.CctTransportBackend( 7842): Status Code: 200

Kommentar der leistungen

Lehrer können Kommentare oder Erklärungen zu Noten schreiben. Diese werden aktuell nicht Angezeigt.
Ich habe keinen Lehrer, der sowas geschrieben hat.

Overflow VPlan Titel

Der titel im VPlan sollte entweder von der Länge begrenzt werden oder als Laufschrift angezeigt werden.

Screenshot_20240121-185726_lanis.png

Mein Unterricht sotieren

Idee

Wäre es möglich die Einträge bei Aktuelles nach ihrem alter zu sortieren und oder die Einträge ausblenden, die keine Daten besitzten?

Elternaccounts

Eltern können Anscheinend auch Accounts habnen.

Unter den Schüleraccounts im bereich "Benutzerdaten" gibt es auch ein Feld "Zugeordnete Eltern/Erziehungsberechtigte"

image

https://support.schulportal.hessen.de/knowledgebase.php?article=606
https://support.schulportal.hessen.de/knowledgebase.php?search=Eltern

Es stellt sich die Frage, wie ein Elternaccount mit "Mein Unterricht" (und evtl. "Nachrichten") umgeht. Es wäre möglich, dass das der Elternaccount zugriff auf die Ansichten des Schülers hat.

App Name

Die App/Repo braucht einen anderen Namen, da sie nicht mehr nur den Vertretungsplan abdeckt. Am Release-Day sollte einer gefunden werden.

Text-Formatierungsfehler

Es gibt bei der Text Formatierung in den Nachrichten Fehler

Das durchstreichen von Text wird nicht angezeigt.
Bei der Uhrzeit werden die Minuten nicht geschrieben.
Wenn Zahlen verschoben werden sollen, werden sie nicht verschoben.

Schulportal Webseite:
image

App:
image

Text:

unterstrichen wird zu _unterstrichen_
entfernt wird zu --entfernt--
- Aufzählung 1
- Aufzählung 2
- Aufzählung 3
Quellcode wird zu Quellcode
Datum v1  12.04.2018 
Datum v1  12.04.18
Datum v2  (12.04.2018) 
Datum v2  (12.04.18)
Uhrzeitenangabe 11:13
Link https://example.com/
Linkkürzung https://example.com/abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz
Email [email protected]
Zahl sonderfall v1 _1
Zahl sonderfall v1 _(1)
Zahlen sonderfall v1 _(123)
Zahl sonderfall v2 ^1
Zahl sonderfall v2 ^(1)
Zahlen sonderfall v2 ^(123)

flutter

Da das automatische herunterladen im hintergund mit capacitorjs nicht wirklich möglich ist, und ich flutter lernen möchte, werde ich die app irgendwann in flutter umschreiben

Kalender Text Fehler

Die Auswahl der Kalender Größe schreibt die Falsche Größe hin. Diese ist auch immer auf Englisch.
Der ganze Kalender ist auf Englisch, aber der Rest auf Deutsch.
Die Überschrift auf "Kalender" ist auf Englisch geschrieben, aber sonst überall auf Deutsch.

school theme loading error

Der häufigste bug auf Countly ist

java.lang.Exception: Null check operator used on a null value

#0      ColorModeNotifier.init (package:sph_plan/themes.dart:69)
<asynchronous suspension>

Nachrichten: konstantes design

Bei ungelesenen Nachrichten sorgt das Glockensymbol dafür, dass die Nachricht nach rechts verschoben wird und die Vorschau dadurch nicht in das Bild der restlichen Nachrichten passt. Vllt. durch einen Benachrichtigungspunkt ersetzen?

Mein Untericht Bug

Die "Mein Unterricht" Seite lädt unendlich lange und es kommt nie ein Ergebnis. (Bei allen drei unter Gruppen)

Wenn bei "Lademodus" in den Einstellungen "Alles laden" einstellt und die App neu startet, ist man im Ladebildschirm gefangen.

Wenn ich es in Android Studio teste bekomme ich diesen fehler:

I/flutter (10759): ----------------FIREBASE CRASHLYTICS----------------
I/flutter (10759): RangeError (index): Invalid value: Valid value range is empty: 0
I/flutter (10759): #0 List.[] (dart:core-patch/growable_array.dart:264:36)
I/flutter (10759): #1 SPHclient.getMeinUnterrichtOverview. (package:sph_plan/client/client.dart:577:65)
I/flutter (10759): #2 SPHclient.getMeinUnterrichtOverview (package:sph_plan/client/client.dart:587:6)
I/flutter (10759):
I/flutter (10759): #3 Fetcher.fetchData. (package:sph_plan/client/fetcher.dart:56:19)
I/flutter (10759):
I/flutter (10759): ----------------------------------------------------
W/FirebaseCrashlytics(10759): Unable to read App Quality Sessions session id.

Google Play Console

(Ich habe noch keinen Zugang, aber sehr bald einen.)

Ich möchte gerne diese App auf den Play Store sehen, obwohl es noch in einer sehr frühen Phase ist (man kann das ja auch als Pre-Release hochladen). Ich hatte auch mal Erfahrung mit Flutter und Dart in der Vergangenheit, somit möchte ich auch irgendwann mithelfen, nachdem ich mein Python-Projekt (LanisAPI) in eine stabile Version gebracht habe.

Wieso?

Diese App sieht am aktivsten aus von der Aktivität und das Kotlin-Projekt von @koenidv ist einfach zu massiv um es wiederzubeleben.
Außerdem wollte ich eigentlich eine eigene App machen, indem ich Frontend mit FastAPI mit meinen Python-Projekt verbinde, aber man muss ja nicht alles immer erneut anfangen.

Mögliche Probleme

Das wird ja eigentlich unter meinen Developer-Namen (kurwjan) veröffentlicht, somit weißt ich nicht wie das mit dem Vertrauen funktioniert, weil eigentlich bin ich irgendein Random Dude aus dem Internet.

Mit dem Hochladen auf dem Play Store kann man dann bestimmt mehr Personen erreichen und somit mehr Bugs herausfinden und etc.

Bessere UI/UX

Bessere UI/UX

Das braucht auf jeden Fall bisschen länger, aber man kann einzelne Commits in Main bringen.

Ziel

Eine einheitliche (const vars für Padding und so weiter, damit jede Seite egal welcher Entwickler gleich aussieht und aufgebaut ist), schöne (und funktionelle) und einfach benutzbare UI, die jeder verstehen sollte.

Ideen

Aktuelle Ideen

Material 3 Guidelines: https://m3.material.io/
Animationen pub package: https://pub.dev/packages/animations (Hat auch Material Motion)

Illustrations?: https://undraw.co/illustrations

  • Error page (besonders wichtig für Bug reporting)
  • Alle (Übersichts-)daten beim Einloggen preloaden mit StreamBuilder und Streams (ähnlich wie Nachrichten Support aufgebaut ist)
    • Man kann auswählen ob man alles preloaden will für eine smoothe Experience oder nur Vp um so schnell wie möglich enttäuscht zu sein.
    • Somit hat man auch ein Cache der alle 15min oder länger reloaded (Vorgeschlagen von @Sukooo)
  • Einrichtungsassistent
  • Besserer Login
  • Drawer ersetzen mit Material 3 NavigationDrawer
    • Erster Widget: Schulhintergrund mit Schülerfoto und Name, und Name der Schule
  • Embedded Webview anstatt Browser zu öffnen
  • Bottom Navbar? Nur als Favoritenleiste, Hauptleiste?
  • Animationen und Transitions nach Material Motion
  • Mehr Material-3-Compliance (Zb. einheitliches Padding in 4dp Schritte)
  • Material You Support
  • Support für größere Bildschirme nach Material Guidelines -> Verschoben
    • Tablets priorisieren

Mögliche Ideen (die auch villt. verschoben werden)

  • Zeige was neu ist in der neuen Version und überprüfe ob es die neuste Version ist.
  • Flutter Spinkit als Easter Egg Option oder so, weil wieso nicht
  • Introduction nach ersten einloggen
  • Jede App hat ein Info-Knopf, um zu zeigen was die einzelnen Elemente bedeuten, wäre ähnlich zu Introduction.
  • Personalisierte Overview page (Aber man kann auswählen ob man Vertretungsplan oder Overview zuerst sehen möchte)
  • Personalisierte Vertretungsplan page

Nein

  • Desktop support
    • Lanis Website ist auf dem PC gut und benutzt man weniger als auf dem handy

Gepushte Ideen

  • Neuer Drawer und Login (#47)
  • BottomBar Favoritenleiste (#49)
  • Cache und vorher laden von Daten (#59)
  • Error widget (#87)
  • Calendar refresh (#88)
  • Nachrichten verbessern und formatieren (#89)
  • Besser login / Setup screen hinzufügen (#95)
  • Mein Unterricht verbessern (#98)
  • Neue Farbeinstellungen (#103)

Aktuelle To-Dos für @kurwjan

  • Daten cachen (und vorher laden, wenn man's will)

  • Error page

  • UI mit zu viel Density erneuern

    • VP: Fertig TODO: Simplify
    • Nachrichten: Fertig
    • Mein Unterricht: Fertig
    • Kalendar: Fertig
    • Ziel: freundlichere UI, auch wenn es heißt nicht effizient die Bildschirmgröße zu benutzen
  • "Einrichtungsassistent" am Anfang

  • Material You und andere Farbeinstellungen

  • Größere Displays unterstützten

    • Nicht einfach scalen mit Displaygröße sondern z.B. mehr Cards oder Listtiles gleichzeitig zeigen und wenn es geht mehr Infos "direkt" zeigen, das heißt Sachen die man erst mit einen Klick darauf sehen kann, könnte man direkt in der Overview Page sehen.
  • Animation

    • Erst machen wenn UI irgendwie finalisiert ist.

lanis auf Knopfdruck im Browser öffnen

Idee

Sobald man sich in der Schule in Lanis einloggt, kann der Browser direkt Geöffnet werden. Dabei übernimmt der Browser den User und dieser kann ohne weitere Eingabe des Passworts auf Lanis zugreifen.

Ich gehe davon aus, dass da eine URL mit der Session ID als Query geöffnet wird. (oder sowas in der Richtung)

Mit einem Button sollte dann Lanis im Browser geöffnet werden können.

F-Droid Idee

Wäre es möglich die App bei F Droid ein zu reichen und verfügbar zu machen?

Proprietary components

Looks like your latest release comes with several proprietary components:

Offending libs:
---------------
* Crashlytics (/com/crashlytics): NonFreeComp,Tracking
* Firebase Data Transport (/com/google/android/datatransport): NonFreeNet
* Google Mobile Services (/com/google/android/gms): NonFreeComp
* Firebase (/com/google/firebase): NonFreeNet,NonFreeComp
* Firebase Installations (/com/google/firebase/installations): NonFreeNet
* FlutterFire (/io/flutter/plugins/firebase): NonFreeNet

6 offenders.

which means I'd have to remove it from my repo – as this exceeds the number of "tolerated offenders". But maybe you can provide an alternative build flavor (and attach its corresponding APK to your releases) which comes without those? You'd need that for your listing with F-Droid anyway. So effective with the next sync (around 7 pm UTC) your app will carry 3 AntiFeatures in my repo (as outlined in above "code quote") instead, in the hope of such a flavor becoming available soon.

Filter

The filter Tab on the app.

passwort zurücksetzen zeigt falsche schule an

Im neuen Login Screen in #95 wurde ein "Passwort zurücksetzen" Button eingefügt.
Dieser öffnet die korrekte URL, um das Passwort zurückzusetzen. Die Webseite zeigt jedoch die Schulinformationen an, die im Localstorage des Browsers gespeichert sind. Dies führt zu 2 Fehlern:

1: Wenn häufig zwischen Schulen gewechselt wird, kann die falsche Schule angezeigt werden, obwohl die richtige URL gewählt wurde.
2: Wenn das SPH vorher nicht im Browser geladen war, werden keine schulspezifischen Informationen geladen.

video: https://drive.google.com/file/d/17TPowrVhX6hvPjW60JjNT6EXI2wvtotV/view?usp=sharing

Login Bug

Wenn man sich erstmals Einloggt nach der neu Installation, bekommt man einen Grauen Bildschirm angezeigt. Nachdem man die App schließt und öffnet geht alles.
Der Bug tritt nicht auf, wenn man seine Daten über die App zurücksetzt.

Bug Report file export

Eine Möglichkeit, Daten aus der Anwendung zu exportieren und an die Entwickler zu senden, damit diese Fehlerberichte besser verfolgen können.
Der Benutzer muss selbst auswählen, welche Daten er exportieren möchte. (eg keine Noten)

Edit: Ich denke es wird Probleme geben wenn die User mit den Entwicklern in Kontakt treten wollen.
Deshalb möchte ich eine dezentrale Datenbank mit Cloudflare Workern erstellen und das Bug-Report Formular direkt in die App integrieren.

Halbjahr

Im Schulportal wird zwischen dem ersten Halbjahr und dem zweitem Halbjahr unterschieden. Deswegen sieht man, wenn das zweite Halbjahr begonnen hat, nur neue Einträge die im neuem Halbjahr passiert sind.
Um alte Einträge von einem Fach zu sehen, wird man auch einen Knopf drücken müssen, der dort sein wird wo jetzt 1. Halbjahr steht.
Dies ist letztes Schuljahr auch so gewesen, weswegen ich schätzte, dass es dieses mal auch so sein wird.

Man kann es jetzt schon testen mit den richtigen URL Parametern.
Beispiel URL: https://start.schulportal.hessen.de/meinunterricht.php?a=sus_view&id=1234&halb=2

Es wäre nützlich, wenn man im zweitem Halbjahr auch die Einträge aus dem erstem Halbjahr einsehen kann.
(Es bezieht sich meines Wissens nach nur auf die Fächer Ansicht und nicht auf die Übersicht)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.