units = new ArrayList<>();
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/app/src/main/java/de/perflyst/untis/view/SortableListViewItem.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.view;
2 |
3 | import android.content.Context;
4 | import android.view.Gravity;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.AbsListView;
8 |
9 | /**
10 | * Lightweight ViewGroup that wraps list items obtained from user's
11 | * ListAdapter. ItemView expects a single child that has a definite
12 | * height (i.e. the child's layout height is not MATCH_PARENT).
13 | * The width of
14 | * ItemView will always match the width of its child (that is,
15 | * the width MeasureSpec given to ItemView is passed directly
16 | * to the child, and the ItemView measured width is set to the
17 | * child's measured width).
18 | *
19 | * The purpose of this class is to optimize slide
20 | * shuffle animations.
21 | */
22 | public class SortableListViewItem extends ViewGroup {
23 |
24 | private int mGravity = Gravity.TOP;
25 |
26 | public SortableListViewItem(Context context) {
27 | super(context);
28 |
29 | setLayoutParams(new AbsListView.LayoutParams(
30 | ViewGroup.LayoutParams.MATCH_PARENT,
31 | ViewGroup.LayoutParams.WRAP_CONTENT));
32 | }
33 |
34 | public void setGravity(int gravity) {
35 | mGravity = gravity;
36 | }
37 |
38 | @Override
39 | protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
40 | final View child = getChildAt(0);
41 |
42 | if (child == null) {
43 | return;
44 | }
45 |
46 | if (mGravity == Gravity.TOP) {
47 | child.layout(0, 0, getMeasuredWidth(), child.getMeasuredHeight());
48 | } else {
49 | child.layout(0, getMeasuredHeight() - child.getMeasuredHeight(), getMeasuredWidth(), getMeasuredHeight());
50 | }
51 | }
52 |
53 | @Override
54 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
55 |
56 | int height = MeasureSpec.getSize(heightMeasureSpec);
57 | int width = MeasureSpec.getSize(widthMeasureSpec);
58 |
59 | int heightMode = MeasureSpec.getMode(heightMeasureSpec);
60 |
61 | final View child = getChildAt(0);
62 | if (child == null) {
63 | setMeasuredDimension(0, width);
64 | return;
65 | }
66 |
67 | if (child.isLayoutRequested()) {
68 | measureChild(child, widthMeasureSpec,
69 | MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
70 | }
71 |
72 | if (heightMode == MeasureSpec.UNSPECIFIED) {
73 | ViewGroup.LayoutParams lp = getLayoutParams();
74 |
75 | if (lp.height > 0) {
76 | height = lp.height;
77 | } else {
78 | height = child.getMeasuredHeight();
79 | }
80 | }
81 |
82 | setMeasuredDimension(width, height);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/app/src/main/java/de/perflyst/untis/view/TimetableItemBackground.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Canvas;
6 | import android.graphics.Color;
7 | import android.graphics.Paint;
8 | import android.graphics.Path;
9 | import android.graphics.PorterDuff;
10 | import android.graphics.PorterDuffXfermode;
11 | import android.graphics.RectF;
12 | import android.util.AttributeSet;
13 | import android.view.View;
14 |
15 | import static de.perflyst.untis.utils.Conversions.dp2px;
16 |
17 | public class TimetableItemBackground extends View {
18 | private final Paint topPaint = new Paint();
19 | private final Paint bottomPaint = new Paint();
20 | private final Paint dividerPaint = new Paint();
21 | private final Paint indicatorPaint = new Paint();
22 | private final Path indicatorPath = new Path();
23 | private int dividerPosition;
24 | private boolean drawIndicator = false;
25 | private Paint maskPaint;
26 | private Paint paint;
27 | private Bitmap maskBitmap;
28 | private float cornerRadius = 0;
29 |
30 | public TimetableItemBackground(Context context, AttributeSet attrs) {
31 | super(context, attrs);
32 | init();
33 | }
34 |
35 | private void init() {
36 | paint = new Paint(Paint.ANTI_ALIAS_FLAG);
37 | maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
38 | maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
39 |
40 | setWillNotDraw(false);
41 | }
42 |
43 | @Override
44 | public void draw(Canvas canvas) {
45 | int width = canvas.getWidth();
46 | int height = canvas.getHeight();
47 |
48 | Bitmap offscreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
49 | Canvas offscreenCanvas = new Canvas(offscreenBitmap);
50 |
51 | super.draw(canvas);
52 |
53 | if (dividerPosition == height) {
54 | offscreenCanvas.drawRect(0, 0, width, height, bottomPaint);
55 | } else if (dividerPosition == 0) {
56 | offscreenCanvas.drawRect(0, 0, width, height, topPaint);
57 | } else {
58 | offscreenCanvas.drawRect(0, 0, width, height - dividerPosition, topPaint);
59 | offscreenCanvas.drawRect(0, height - dividerPosition, width, height, bottomPaint);
60 | offscreenCanvas.drawRect(0, height - dividerPosition - dp2px(1), width, height - dividerPosition + dp2px(1), dividerPaint);
61 | }
62 |
63 | if (drawIndicator) {
64 | if (indicatorPath.isEmpty()) {
65 | indicatorPath.moveTo(width - dp2px(8), height);
66 | indicatorPath.lineTo(width, height);
67 | indicatorPath.lineTo(width, height - dp2px(8));
68 | indicatorPath.close();
69 | }
70 |
71 | offscreenCanvas.drawPath(indicatorPath, indicatorPaint);
72 | }
73 |
74 | if (maskBitmap == null)
75 | maskBitmap = createMask(canvas.getWidth(), canvas.getHeight());
76 |
77 | offscreenCanvas.drawBitmap(maskBitmap, 0, 0, maskPaint);
78 | canvas.drawBitmap(offscreenBitmap, 0, 0, paint);
79 | }
80 |
81 | public void setTopColor(int topColor) {
82 | topPaint.setColor(topColor);
83 | }
84 |
85 | public void setBottomColor(int bottomColor) {
86 | bottomPaint.setColor(bottomColor);
87 | }
88 |
89 | public void setDividerColor(int dividerColor) {
90 | dividerPaint.setColor(dividerColor);
91 | }
92 |
93 | public void setDividerPosition(int dividerPosition) {
94 | this.dividerPosition = dividerPosition;
95 | }
96 |
97 | public void setIndicatorColor(int color) {
98 | this.drawIndicator = true;
99 | this.indicatorPaint.setStyle(Paint.Style.FILL);
100 | this.indicatorPaint.setColor(color);
101 | }
102 |
103 | private Bitmap createMask(int width, int height) {
104 | Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
105 | Canvas c = new Canvas(mask);
106 |
107 | Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
108 | paint.setColor(Color.WHITE);
109 | c.drawRect(0, 0, width, height, paint);
110 |
111 | paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
112 | c.drawRoundRect(new RectF(0, 0, width, height), cornerRadius, cornerRadius, paint);
113 |
114 | return mask;
115 | }
116 |
117 | public void setCornerRadius(int cornerRadius) {
118 | this.cornerRadius = cornerRadius;
119 | }
120 | }
--------------------------------------------------------------------------------
/app/src/main/java/de/perflyst/untis/view/VerticalTextView.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Canvas;
5 | import android.text.TextPaint;
6 | import android.view.Gravity;
7 |
8 | public class VerticalTextView extends android.support.v7.widget.AppCompatTextView {
9 | private final boolean topDown;
10 |
11 | public VerticalTextView(Context context) {
12 | super(context);
13 | final int gravity = getGravity();
14 | if (Gravity.isVertical(gravity) && (gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.BOTTOM) {
15 | setGravity((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) | Gravity.TOP);
16 | topDown = false;
17 | } else
18 | topDown = true;
19 | }
20 |
21 | @Override
22 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
23 | //noinspection SuspiciousNameCombination
24 | super.onMeasure(heightMeasureSpec, widthMeasureSpec);
25 | setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
26 | }
27 |
28 | @Override
29 | protected void onDraw(Canvas canvas) {
30 | TextPaint textPaint = getPaint();
31 | textPaint.setColor(getCurrentTextColor());
32 | textPaint.drawableState = getDrawableState();
33 |
34 | canvas.save();
35 |
36 | if (topDown) {
37 | canvas.translate(getWidth(), 0);
38 | canvas.rotate(90);
39 | } else {
40 | canvas.translate(0, getHeight());
41 | canvas.rotate(-90);
42 | }
43 |
44 |
45 | canvas.translate(getCompoundPaddingLeft(), getExtendedPaddingTop());
46 |
47 | getLayout().draw(canvas);
48 | canvas.restore();
49 | }
50 | }
--------------------------------------------------------------------------------
/app/src/main/java/de/perflyst/untis/view/VerticalViewPager.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.support.annotation.NonNull;
6 | import android.support.v4.view.ViewPager;
7 | import android.util.AttributeSet;
8 | import android.view.MotionEvent;
9 | import android.view.View;
10 |
11 | /**
12 | * Uses a combination of a PageTransformer and swapping X & Y coordinates
13 | * of touch events to create the illusion of a vertically scrolling ViewPager.
14 | *
15 | * Source: StackOverflow
16 | */
17 | public class VerticalViewPager extends ViewPager {
18 |
19 | public VerticalViewPager(Context context) {
20 | super(context);
21 | init();
22 | }
23 |
24 | public VerticalViewPager(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | init();
27 | }
28 |
29 | private void init() {
30 | // The majority of the magic happens here
31 | setPageTransformer(true, new VerticalPageTransformer());
32 | // The easiest way to get rid of the overscroll drawing that happens on the left and right
33 | setOverScrollMode(OVER_SCROLL_NEVER);
34 | }
35 |
36 | /**
37 | * Swaps the X and Y coordinates of your touch event.
38 | */
39 | private MotionEvent swapXY(MotionEvent ev) {
40 | float width = getWidth();
41 | float height = getHeight();
42 |
43 | float newX = (ev.getY() / height) * width;
44 | float newY = (ev.getX() / width) * height;
45 |
46 | ev.setLocation(newX, newY);
47 |
48 | return ev;
49 | }
50 |
51 | @Override
52 | public boolean onInterceptTouchEvent(MotionEvent ev) {
53 | boolean intercepted = super.onInterceptTouchEvent(swapXY(ev));
54 | swapXY(ev); // return touch coordinates to original reference frame for any child views
55 | return intercepted;
56 | }
57 |
58 | @SuppressLint("ClickableViewAccessibility")
59 | @Override
60 | public boolean onTouchEvent(MotionEvent ev) {
61 | return super.onTouchEvent(swapXY(ev));
62 | }
63 |
64 | @Override
65 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
66 | if (getChildCount() < 1)
67 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
68 |
69 | int height = 0;
70 | for (int i = 0; i < getChildCount(); i++) {
71 | View child = getChildAt(i);
72 | child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
73 | if (child.getMeasuredHeight() > height)
74 | height = child.getMeasuredHeight();
75 | }
76 |
77 | super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
78 | }
79 |
80 | private class VerticalPageTransformer implements ViewPager.PageTransformer {
81 |
82 | @Override
83 | public void transformPage(@NonNull View view, float position) {
84 |
85 | if (position < -1) { // [-Infinity,-2)
86 | // This page is way off-screen to the left.
87 | view.setAlpha(0);
88 |
89 | } else if (position <= 1) { // [-1,1]
90 | view.setAlpha(1);
91 |
92 | // Counteract the default slide transition
93 | view.setTranslationX(view.getWidth() * -position);
94 |
95 | //set Y position to swipe in from top
96 | float yPosition = position * view.getHeight();
97 | view.setTranslationY(yPosition);
98 |
99 | } else { // (2,+Infinity]
100 | // This page is way off-screen to the right.
101 | view.setAlpha(0);
102 | }
103 | }
104 | }
105 | }
--------------------------------------------------------------------------------
/app/src/main/java/de/perflyst/untis/view/behavior/ScrollAwareFABBehavior.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.view.behavior;
2 |
3 | import android.content.Context;
4 | import android.support.annotation.NonNull;
5 | import android.support.design.widget.CoordinatorLayout;
6 | import android.support.design.widget.FloatingActionButton;
7 | import android.support.design.widget.FloatingActionButton.Behavior;
8 | import android.support.v4.view.ViewCompat;
9 | import android.util.AttributeSet;
10 | import android.view.View;
11 |
12 | @SuppressWarnings("unused") // This is used in layouts (activity_room_finder.xml)
13 | public class ScrollAwareFABBehavior extends Behavior {
14 | public ScrollAwareFABBehavior(Context context, AttributeSet attrs) {
15 | super();
16 | }
17 |
18 | @Override
19 | public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout,
20 | @NonNull FloatingActionButton child, @NonNull View directTargetChild,
21 | @NonNull View target, int nestedScrollAxes, int type) {
22 | return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL ||
23 | super.onStartNestedScroll(coordinatorLayout, child, directTargetChild,
24 | target, nestedScrollAxes, type);
25 | }
26 |
27 | @Override
28 | public void onNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull FloatingActionButton child,
29 | @NonNull View target, int dxConsumed, int dyConsumed,
30 | int dxUnconsumed, int dyUnconsumed, int type) {
31 | super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed,
32 | dxUnconsumed, dyUnconsumed, type);
33 |
34 | if (dyConsumed > 0 && child.getVisibility() == View.VISIBLE)
35 | child.hide(new FloatingActionButton.OnVisibilityChangedListener() {
36 | @Override
37 | public void onHidden(FloatingActionButton fab) {
38 | super.onShown(fab);
39 | fab.setVisibility(View.INVISIBLE);
40 | }
41 | });
42 | else if (dyConsumed < 0 && child.getVisibility() != View.VISIBLE)
43 | child.show();
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_stat_timetable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/drawable-hdpi/ic_stat_timetable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_stat_timetable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/drawable-mdpi/ic_stat_timetable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_add_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_arrow_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_arrow_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_calendar.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_delete.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_error.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_notifications.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_personal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_roomfinder.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_styling.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/ic_prefs_timetable.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/non_selected_item_indicator_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/selected_item_indicator_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v21/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_stat_timetable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/drawable-xhdpi/ic_stat_timetable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_stat_timetable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/drawable-xxhdpi/ic_stat_timetable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxxhdpi/ic_stat_timetable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/drawable-xxxhdpi/ic_stat_timetable.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_add_circle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_left.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_arrow_right.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_calendar.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_check.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_classes.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_delete.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_drag_handle.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_error.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
12 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_failed.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_gift.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_info.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_notifications.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_personal.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_roomfinder.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_styling.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_prefs_timetable.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_room_available.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_room_occupied.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_rooms.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_search_rooms.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_settings.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_share.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_suggested_features.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_teacher.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/non_selected_item_indicator_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selected_item_indicator_dot.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
11 |
12 |
14 |
15 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/side_nav_bar.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_login_data_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
14 |
15 |
19 |
20 |
21 |
22 |
30 |
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_room_finder.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
27 |
28 |
36 |
37 |
43 |
44 |
55 |
56 |
65 |
66 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_login_data_input.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/app_bar_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/borderless_button.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_header.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_login.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
17 |
18 |
27 |
28 |
38 |
39 |
46 |
47 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
19 |
20 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |
48 |
49 |
53 |
54 |
58 |
59 |
64 |
65 |
66 |
67 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
86 |
87 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/content_timetable.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_timetable_item_detail_page_info.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
21 |
22 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/dialog_timetable_item_details.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/grid_view_item_checkboxes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_day.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_hour.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
21 |
22 |
31 |
32 |
45 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_features.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
19 |
20 |
32 |
33 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_features_text.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_room_finder.xml:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
21 |
22 |
31 |
32 |
44 |
45 |
54 |
55 |
61 |
62 |
68 |
69 |
70 |
82 |
83 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/nav_header_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
23 |
24 |
32 |
33 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/table_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
15 |
29 |
30 |
44 |
45 |
54 |
55 |
67 |
68 |
--------------------------------------------------------------------------------
/app/src/main/res/menu-v21/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/activity_main_drawer.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
11 |
15 |
19 |
23 |
24 |
25 |
26 |
27 |
29 | -
33 |
34 | -
38 |
39 |
40 |
41 |
43 | -
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
10 |
11 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/.strings.xml.swp:
--------------------------------------------------------------------------------
1 | b0nano 2.5.3 AI user pc-02 app/src/main/res/values/strings.xml
--------------------------------------------------------------------------------
/app/src/main/res/values/arrays.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - @string/theme_default
5 | - @string/theme_untis
6 | - @string/theme_blue
7 | - @string/theme_green
8 | - @string/theme_pink
9 | - @string/theme_cyan
10 |
11 |
12 |
13 | - default
14 | - untis
15 | - blue
16 | - green
17 | - pink
18 | - cyan
19 |
20 |
21 |
22 | - @string/preference_notifications_visibility_hidden
23 | - @string/preference_notifications_visibility_short
24 | - @string/preference_notifications_visibility_long
25 |
26 |
27 |
28 | - hidden
29 | - short
30 | - long
31 |
32 |
33 |
34 | - antiope.webuntis.com
35 | - aoide.webuntis.com
36 | - arche.webuntis.com
37 | - asopo.webuntis.com
38 | - borys.webuntis.com
39 | - cissa.webuntis.com
40 | - demo.webuntis.com
41 | - erato.webuntis.com
42 | - euterpe.webuntis.com
43 | - hepta.webuntis.com
44 | - hydra.webuntis.com
45 | - hypate.webuntis.com
46 | - iris.webuntis.com
47 | - jira.webuntis.com
48 | - kalliope.webuntis.com
49 | - kephiso.webuntis.com
50 | - kerberos.webuntis.com
51 | - klio.webuntis.com
52 | - melete.webuntis.com
53 | - melpomene.webuntis.com
54 | - mese.webuntis.com
55 | - neilo.webuntis.com
56 | - nete.webuntis.com
57 | - poly.webuntis.com
58 | - terpsichore.webuntis.com
59 | - thalia.webuntis.com
60 | - tipo.webuntis.com
61 | - urania.webuntis.com
62 |
63 |
64 |
--------------------------------------------------------------------------------
/app/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #f44336
4 | #d32f2f
5 | #448aff
6 | #212121
7 | #757575
8 | #e0e0e0
9 |
10 | #ff9800
11 | #f57c00
12 |
13 | #03a9f4
14 | #0288d1
15 | #ff5722
16 |
17 | #4caf50
18 | #388e3c
19 | #607d8b
20 |
21 | #e91e63
22 | #c2185b
23 | #536dfe
24 |
25 | #00bcd4
26 | #0097a7
27 | #ff4081
28 |
29 | #fff44336
30 | #ff4caf50
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/values/defaults.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | false
5 | false
6 | false
7 | false
8 | false
9 | false
10 | true
11 | false
12 | true
13 | true
14 | false
15 |
16 | 0xFFEEEEEE
17 | 0xFFF44336
18 | 0xFFD32F2F
19 | 0xFF03A9F4
20 | 0xFF0288D1
21 | 0xFF4CAF50
22 | 0xFF388E3C
23 | 0xFF9E9E9E
24 | 0xFF616161
25 | 0xFFFFCDD2
26 | 0xFFFFFFFF
27 | 2
28 | 2
29 | 12
30 | 10
31 | 30
32 |
33 | default
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 | 16dp
3 | 160dp
4 | 16dp
5 | 16dp
6 | 18sp
7 | 11sp
8 | 38dp
9 | 48dp
10 | 11sp
11 | 15sp
12 | 12sp
13 | 10sp
14 | 4dp
15 | 6dp
16 | 8dp
17 |
--------------------------------------------------------------------------------
/app/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/static.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 0xFFEEEEEE
4 | 0xFF363636
5 |
--------------------------------------------------------------------------------
/app/src/main/res/xml-de/remote_config_defaults.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | recommendation_subject
5 | Verwende OpenUntis!
6 |
7 |
8 | recommendation_text
9 | Genug von der originalen Untis Mobile App? Verwende OpenUntis! Mehr Informationen
10 | auf https://github.com/Perflyst/OpenUntis
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/backup_descriptor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_about.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
12 |
13 |
16 |
17 |
18 |
21 |
24 |
25 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_account.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
7 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_headers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
12 |
13 |
17 |
18 |
22 |
23 |
27 |
28 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_notifications.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 |
26 |
27 |
30 |
31 |
36 |
37 |
39 |
40 |
48 |
49 |
57 |
58 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_roomfinder.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
8 |
9 |
13 |
14 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/prefs_timetable.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
12 |
13 |
14 |
22 |
23 |
24 |
32 |
33 |
34 |
36 |
37 |
41 |
42 |
46 |
47 |
48 |
56 |
57 |
58 |
66 |
67 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/xml/remote_config_defaults.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | recommendation_subject
5 | Try out OpenUntis!
6 |
7 |
8 | recommendation_text
9 | Tired of the default Untis Mobile app? Use OpenUntis! More information at
10 | https://github.com/Perflyst/OpenUntis
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/test/java/de/perflyst/untis/test/ConversionsTest.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.test;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.util.DisplayMetrics;
6 |
7 | import de.perflyst.untis.utils.Conversions;
8 |
9 | import org.junit.Rule;
10 | import org.junit.Test;
11 | import org.junit.rules.ExpectedException;
12 |
13 | import static org.hamcrest.CoreMatchers.is;
14 | import static org.hamcrest.MatcherAssert.assertThat;
15 | import static org.mockito.Mockito.mock;
16 | import static org.mockito.Mockito.when;
17 |
18 | public class ConversionsTest {
19 | @Rule
20 | public ExpectedException exceptionGrabber = ExpectedException.none();
21 |
22 | @Test(expected = RuntimeException.class)
23 | public void dateOperations_constructor() {
24 | new Conversions();
25 | }
26 |
27 | @Test
28 | public void conversions_dp2px() {
29 | DisplayMetrics metrics = mock(DisplayMetrics.class);
30 |
31 | Resources resources = mock(Resources.class);
32 | when(resources.getDisplayMetrics())
33 | .thenReturn(metrics);
34 |
35 | Context context = mock(Context.class);
36 | when(context.getResources())
37 | .thenReturn(resources);
38 |
39 |
40 | metrics.density = 1.5f;
41 |
42 | Conversions.setScale(context);
43 | assertThat(Conversions.dp2px(12), is(18));
44 |
45 |
46 | metrics.density = 2;
47 |
48 | Conversions.setScale(context);
49 | assertThat(Conversions.dp2px(12), is(24));
50 | }
51 |
52 | @Test
53 | public void conversions_dp2px_noScale() {
54 | exceptionGrabber.expect(IllegalStateException.class);
55 | Conversions.dp2px(12);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/test/java/de/perflyst/untis/test/SessionInfoTest.java:
--------------------------------------------------------------------------------
1 | package de.perflyst.untis.test;
2 |
3 | import de.perflyst.untis.utils.ElementName;
4 | import de.perflyst.untis.utils.SessionInfo;
5 |
6 | import org.json.JSONException;
7 | import org.json.JSONObject;
8 | import org.junit.Test;
9 |
10 | import static org.hamcrest.CoreMatchers.is;
11 | import static org.hamcrest.MatcherAssert.assertThat;
12 |
13 | public class SessionInfoTest {
14 | @Test
15 | public void sessionInfo_constructor() {
16 | SessionInfo sessionInfo = new SessionInfo();
17 |
18 | assertThat(sessionInfo.getElemId(), is(-1));
19 | assertThat(sessionInfo.getElemType(), is(""));
20 | assertThat(sessionInfo.getDisplayName(), is(""));
21 | }
22 |
23 | @Test
24 | public void sessionInfo_set_get() {
25 | SessionInfo sessionInfo = new SessionInfo();
26 |
27 | sessionInfo.setElemId(10);
28 | sessionInfo.setElemType("Test");
29 | sessionInfo.setDisplayName("Test");
30 |
31 | assertThat(sessionInfo.getElemId(), is(10));
32 | assertThat(sessionInfo.getElemType(), is("Test"));
33 | assertThat(sessionInfo.getDisplayName(), is("Test"));
34 | }
35 |
36 | @Test
37 | public void sessionInfo_setDataFromJsonObject() throws JSONException {
38 | SessionInfo sessionInfo = new SessionInfo();
39 |
40 | JSONObject data = new JSONObject();
41 |
42 | sessionInfo.setDataFromJsonObject(data);
43 |
44 | assertThat(sessionInfo.getElemId(), is(-1));
45 | assertThat(sessionInfo.getElemType(), is(""));
46 | assertThat(sessionInfo.getDisplayName(), is("OpenUntis"));
47 |
48 | data.put("elemId", 10);
49 | data.put("elemType", "Test");
50 | data.put("displayName", "Test");
51 |
52 | sessionInfo.setDataFromJsonObject(data);
53 |
54 | assertThat(sessionInfo.getElemId(), is(10));
55 | assertThat(sessionInfo.getElemType(), is("Test"));
56 | assertThat(sessionInfo.getDisplayName(), is("Test"));
57 | }
58 |
59 | @Test
60 | public void sessionInfo_getElemTypeName() {
61 | assertThat(SessionInfo.getElemTypeName(ElementName.ElementType.STUDENT), is("STUDENT"));
62 | assertThat(SessionInfo.getElemTypeName(ElementName.ElementType.CLASS), is("CLASS"));
63 | assertThat(SessionInfo.getElemTypeName(ElementName.ElementType.TEACHER), is("TEACHER"));
64 | assertThat(SessionInfo.getElemTypeName(ElementName.ElementType.ROOM), is("ROOM"));
65 | assertThat(SessionInfo.getElemTypeName(ElementName.ElementType.UNKNOWN), is(""));
66 | }
67 |
68 | @Test
69 | public void sessionInfo_getElemTypeId() {
70 | assertThat(SessionInfo.getElemTypeId("STUDENT"), is(ElementName.ElementType.STUDENT));
71 | assertThat(SessionInfo.getElemTypeId("CLASS"), is(ElementName.ElementType.CLASS));
72 | assertThat(SessionInfo.getElemTypeId("TEACHER"), is(ElementName.ElementType.TEACHER));
73 | assertThat(SessionInfo.getElemTypeId("ROOM"), is(ElementName.ElementType.ROOM));
74 | assertThat(SessionInfo.getElemTypeId(""), is(ElementName.ElementType.UNKNOWN));
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | maven {
7 | url "https://plugins.gradle.org/m2/"
8 | }
9 | google()
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.1.4'
13 | classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3"
14 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
15 | // NOTE: Do not place your application dependencies here; they belong
16 | // in the individual module build.gradle files
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | google()
23 | jcenter()
24 | }
25 | }
26 |
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
30 |
--------------------------------------------------------------------------------
/color-picker-view/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion '27.0.3'
6 | resourcePrefix "colorpickerview__"
7 |
8 | defaultConfig {
9 | minSdkVersion 15
10 | targetSdkVersion 27
11 | versionCode 4
12 | versionName "1.4.0"
13 | }
14 | buildTypes {
15 | }
16 | return void
17 | }
18 |
19 | dependencies {
20 | implementation fileTree(dir: 'libs', include: ['*.jar'])
21 | implementation 'com.android.support:support-annotations:28.0.0-alpha1'
22 | }
--------------------------------------------------------------------------------
/color-picker-view/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/java/com/github/danielnilsson9/colorpickerview/ColorUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Daniel Nilsson
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package com.github.danielnilsson9.colorpickerview;
17 |
18 | import android.graphics.Color;
19 |
20 | import java.util.regex.Pattern;
21 |
22 | public class ColorUtils {
23 | /**
24 | * Format for #AARRGGBB and #RRGGBB.
25 | **/
26 | private final static Pattern HEXADECIMAL_FORMAT = Pattern.compile("^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6})$");
27 | /**
28 | * Format for #RGB
29 | **/
30 | private final static Pattern HEXADECIMAL_SHORT_FORMAT = Pattern.compile("^#([A-Fa-f0-9]{3})$");
31 |
32 | /**
33 | * Check if the provided color code is valid according to the following hexadecimal color formats:
34 | * #AARRGGBB, #RRGGBB or #RGB.
35 | *
36 | * @param colorCode color code to check
37 | * @return {@code true} color code is valid according to the formats
38 | */
39 | public static boolean isValidHexadecimal(String colorCode) {
40 | return HEXADECIMAL_FORMAT.matcher(colorCode).matches() ||
41 | HEXADECIMAL_SHORT_FORMAT.matcher(colorCode).matches();
42 | }
43 |
44 | /**
45 | * Parse the color code, and return the corresponding color-int.
46 | * If the string cannot be parsed, throws an IllegalArgumentException
47 | * exception. Supported formats are:
48 | * #RRGGBB
49 | * #AARRGGBB
50 | * #RGB
51 | *
52 | * @param colorCode color code to parse
53 | * @return color-int
54 | */
55 | public static int parseColor(String colorCode) {
56 | if (HEXADECIMAL_SHORT_FORMAT.matcher(colorCode).matches()) {
57 | colorCode = String.format("#%c%c%c%c%c%c", colorCode.charAt(1), colorCode.charAt(1),
58 | colorCode.charAt(2), colorCode.charAt(2), colorCode.charAt(3), colorCode.charAt(3));
59 | }
60 | return Color.parseColor(colorCode);
61 | }
62 |
63 | /**
64 | * Convert a color-int into a color hexadecimal string.
65 | * Format will be #AARRGGBB if includeAlpha is true, or #RRGGBB if is false.
66 | *
67 | * @param color color int
68 | * @param includeAlpha if true hexadecimal will include alpha channel
69 | * @return color code for the color-int specified and based on the includeAlpha
70 | */
71 | public static String colorToString(int color, boolean includeAlpha) {
72 | if (includeAlpha) {
73 | return "#" + Integer.toHexString(color);
74 | } else {
75 | return "#" + Integer.toHexString(color).substring(2);
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/java/com/github/danielnilsson9/colorpickerview/preference/ColorPreference.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2015 Daniel Nilsson
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.github.danielnilsson9.colorpickerview.preference;
18 |
19 | import android.content.Context;
20 | import android.content.res.TypedArray;
21 | import android.preference.Preference;
22 | import android.util.AttributeSet;
23 | import android.view.View;
24 |
25 | import com.github.danielnilsson9.colorpickerview.R;
26 | import com.github.danielnilsson9.colorpickerview.view.ColorPanelView;
27 |
28 | public class ColorPreference extends Preference {
29 |
30 | private OnShowDialogListener mListener;
31 | private int mColor = 0xFF000000;
32 |
33 | public ColorPreference(Context context, AttributeSet attrs) {
34 | super(context, attrs);
35 | init();
36 | }
37 |
38 |
39 | public ColorPreference(Context context, AttributeSet attrs, int defStyle) {
40 | super(context, attrs, defStyle);
41 | init();
42 |
43 | }
44 |
45 | private void init() {
46 | setPersistent(true);
47 |
48 | setWidgetLayoutResource(R.layout.colorpickerview__preference_preview_layout);
49 |
50 | setOnPreferenceClickListener(new OnPreferenceClickListener() {
51 |
52 | @Override
53 | public boolean onPreferenceClick(Preference preference) {
54 |
55 | if (mListener != null) {
56 | mListener.onShowColorPickerDialog((String) getTitle(), mColor);
57 | return true;
58 | } else {
59 | throw new IllegalArgumentException(
60 | "You must first call setOnShowDialogListener() and "
61 | + "handle showing the ColorPickerDialogFragment yourself.");
62 | }
63 | }
64 | });
65 | }
66 |
67 | /**
68 | * Since the color picker dialog is now a DialogFragment
69 | * this preference cannot take care of showing it without
70 | * access to the fragment manager. Therefore I leave it up to
71 | * you to actually show the dialog once the preference is clicked.
72 | *
73 | * Call saveValue() once you have a color to save.
74 | *
75 | * @param listener OnShowDialogListener
76 | */
77 | public void setOnShowDialogListener(OnShowDialogListener listener) {
78 | mListener = listener;
79 | }
80 |
81 | @Override
82 | protected void onBindView(View view) {
83 | super.onBindView(view);
84 |
85 | ColorPanelView preview = view.findViewById(R.id.colorpickerview__preference_preview_color_panel);
86 |
87 | if (preview != null) {
88 | preview.setColor(mColor);
89 | }
90 |
91 | }
92 |
93 | @Override
94 | protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
95 | if (restorePersistedValue) {
96 | mColor = getPersistedInt(0xFF000000);
97 | //Log.d("mColorPicker", "Load saved color: " + mColor);
98 | } else {
99 | mColor = (Integer) defaultValue;
100 | persistInt(mColor);
101 | }
102 | }
103 |
104 | @Override
105 | protected Object onGetDefaultValue(TypedArray a, int index) {
106 | return a.getInteger(index, 0xFF000000);
107 | }
108 |
109 | public void saveValue(int color) {
110 | mColor = color;
111 | persistInt(mColor);
112 | notifyChanged();
113 | }
114 |
115 |
116 | public interface OnShowDialogListener {
117 | void onShowColorPickerDialog(String title, int currentColor);
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/java/com/github/danielnilsson9/colorpickerview/view/DrawingUtils.java:
--------------------------------------------------------------------------------
1 | package com.github.danielnilsson9.colorpickerview.view;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.util.TypedValue;
6 |
7 | class DrawingUtils {
8 |
9 | static int dpToPx(Context c, float dipValue) {
10 | DisplayMetrics metrics = c.getResources().getDisplayMetrics();
11 |
12 | float val = TypedValue.applyDimension(
13 | TypedValue.COMPLEX_UNIT_DIP, dipValue, metrics);
14 |
15 | // Round
16 | int res = (int) (val + 0.5);
17 |
18 | // Ensure at least 1 pixel if val was > 0
19 | if (res == 0 && val > 0) {
20 | res = 1;
21 | }
22 |
23 | return res;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/drawable/colorpickerview__btn_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/drawable/colorpickerview__btn_background_pressed.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | -
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/layout/colorpickerview__dialog_color_picker.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
24 |
25 |
29 |
30 |
34 |
35 |
43 |
44 |
45 |
46 |
56 |
57 |
64 |
65 |
70 |
71 |
75 |
76 |
85 |
86 |
90 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/layout/colorpickerview__preference_preview_layout.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-de/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hexadezimal
4 | OK
5 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-sw360dp/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 65dp
5 | 40dp
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-sw360dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-sw400dp/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 70dp
5 | 40dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-sw400dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-sw600dp/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values/dimen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 6dp
5 |
6 | 65dp
7 | 32dp
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hexadecimal
4 | OK
5 | ↓
6 |
--------------------------------------------------------------------------------
/color-picker-view/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
15 |
16 |
22 |
23 |
--------------------------------------------------------------------------------
/docs/setup-proxy.md:
--------------------------------------------------------------------------------
1 | # Proxied WebUntis
2 |
3 | To enhance your privacy you can proxy webuntis.com through a server. This will reduce the leakage of your IP and useragent to webuntis.com
4 |
5 |
6 | ### nginx
7 |
8 | Please note that the security (SSL) headers may need to be changed depending on your OS and nginx version.
9 | You can also completely remove them, they are optional and do not change functionality in general.
10 |
11 | Change `demo` to the server you want to proxy.
12 |
13 | ```
14 | server {
15 | listen :80;
16 | listen :80;
17 | server_name demo.openuntis.example.com;
18 |
19 | location /.well-known/acme-challenge/ { allow all; }
20 | location / { return 301 https://$host$request_uri; }
21 |
22 | access_log /dev/null;
23 | error_log /dev/null;
24 | }
25 |
26 | server {
27 | listen :443 ssl http2;
28 | listen :443 ssl http2;
29 |
30 | server_name demo.openuntis.example.com;
31 |
32 | access_log /dev/null;
33 | error_log /dev/null;
34 |
35 | # optional security headers (may need to be changed!)
36 | #ssl_protocols TLSv1.2;
37 | #ssl_prefer_server_ciphers on;
38 | #ssl_dhparam /etc/nginx/dhparam.pem;
39 | #ssl_ciphers EECDH+AESGCM:EDH+AESGCM;
40 | #ssl_ecdh_curve secp384r1;
41 | #ssl_session_timeout 10m;
42 | #ssl_session_cache shared:SSL:10m;
43 | #ssl_session_tickets off;
44 | #add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
45 | #add_header X-Frame-Options DENY;
46 | #add_header X-Content-Type-Options nosniff;
47 | #add_header X-XSS-Protection "1; mode=block";
48 | #add_header Referrer-Policy "no-referrer";
49 | #add_header Expect-CT "enforce, max-age=21600";
50 |
51 | # you can also use a wildcard certificate here if you want to proxy multiple webuntis server
52 | ssl_certificate /etc/letsencrypt/live/demo.openuntis.example.com/fullchain.pem;
53 | ssl_certificate_key /etc/letsencrypt/live/demo.openuntis.example.com/privkey.pem;
54 | ssl_trusted_certificate /etc/letsencrypt/live/demo.openuntis.example.com/chain.pem;
55 |
56 | client_max_body_size 0;
57 | location / {
58 | proxy_pass https://demo.webuntis.com;
59 | proxy_redirect https://demo.webuntis.com/ /;
60 | proxy_set_header Host demo.webuntis.com;
61 | # we do not want to leak any IP, if you want uncomment below
62 | # proxy_set_header X-Real-IP $remote_addr;
63 | # proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
64 | # proxy_set_header X-Forwarded-Host $server_name;
65 |
66 | # pass firefox esr header
67 | proxy_set_header User-Agent "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0";
68 | sub_filter_types text/html, application/json;
69 | sub_filter_once off;
70 | sub_filter "demo.webuntis.com" "demo.openuntis.example.com";
71 | }
72 | }
73 | ```
74 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # org.gradle.jvmargs=-Xmx1536m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Perflyst/OpenUntis/7e4db94ccd2cd1269d3ee695e792c066d0b495a7/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jun 06 08:39:22 CEST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':color-picker-view'
--------------------------------------------------------------------------------