Commit b74f6d85 authored by Lennart Bader's avatar Lennart Bader
Browse files

Added additional classes to AccountFragment and PlanFragment.

parent 2b20c13f
Pipeline #18 passed with stage
in 54 seconds
......@@ -40,6 +40,11 @@ public class PlanEntryHolder extends RecyclerView.ViewHolder {
subst.setText(planEntry.getSubstitution());
comment.setText(planEntry.getComment());
cls.setText(planEntry.getCls());
if (planEntry.isOwn()) {
cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorPrimaryLight));
} else {
cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorSecondaryLight));
}
}
public void setOnClickListener(CardView.OnClickListener listener) {
......
......@@ -7,6 +7,7 @@ import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.util.ArraySet;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
......@@ -31,7 +32,10 @@ import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.net.ssl.HttpsURLConnection;
......@@ -99,6 +103,27 @@ public class MyTFGApi {
return user;
}
public List<String> getAdditionalClasses() {
SharedPreferences preferences = context.getSharedPreferences("authmanager", Context.MODE_PRIVATE);
Set<String> set = preferences.getStringSet("additional_classes", new android.support.v4.util.ArraySet<String>());
List<String> list = new LinkedList<>();
for (String cls : set) {
list.add(cls);
}
return list;
}
public void setAdditionalClasses(List<String> classes) {
Set<String> classSet = new android.support.v4.util.ArraySet<>(classes.size());
for (String cls : classes) {
classSet.add(cls);
}
SharedPreferences preferences = context.getSharedPreferences("authmanager", Context.MODE_PRIVATE);
preferences.edit()
.putStringSet("additional_classes", classSet)
.apply();
}
/**
* Generates the device ID passed to the API.
* @return The device ID.
......
package de.mytfg.apps.vplan.fragments;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
......@@ -8,6 +11,10 @@ import android.support.annotation.StringDef;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.Snackbar;
import android.support.v4.app.Fragment;
import android.support.v4.text.TextUtilsCompat;
import android.support.v7.app.AlertDialog;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
......@@ -16,17 +23,30 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import de.mytfg.apps.vplan.R;
import de.mytfg.apps.vplan.activities.MainActivity;
import de.mytfg.apps.vplan.api.ApiCallback;
import de.mytfg.apps.vplan.api.ApiParams;
import de.mytfg.apps.vplan.api.MyTFGApi;
import de.mytfg.apps.vplan.objects.User;
public class AccountFragment extends Fragment {
private View view;
private MainActivity context;
public AccountFragment() {
......@@ -37,6 +57,7 @@ public class AccountFragment extends Fragment {
public View onCreateView(LayoutInflater inflater, @Nullable final ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_account, container, false);
final MainActivity context = (MainActivity)this.getActivity();
this.context = context;
setHasOptionsMenu(true);
context.getToolbarManager()
.clear()
......@@ -44,19 +65,25 @@ public class AccountFragment extends Fragment {
.setExpandable(true, true);
MyTFGApi api = new MyTFGApi(context);
String username = api.getUsername();
String device = api.getStoredDevice();
long expirets = api.getExpire();
String expire = api.getExpireString();
final User user = api.getUser();
TextView title = (TextView) view.findViewById(R.id.account_name);
TextView tv_username = (TextView) view.findViewById(R.id.account_info_username);
TextView tv_device = (TextView) view.findViewById(R.id.account_info_device);
TextView tv_expire = (TextView) view.findViewById(R.id.account_info_expire);
title.setText(username);
tv_username.setText(String.format(getString(R.string.account_info_username), username));
tv_device.setText(String.format(getString(R.string.account_info_device), device));
tv_expire.setText(String.format(getString(R.string.account_info_expire), expire));
TextView username = (TextView) view.findViewById(R.id.account_name);
username.setText(user.getUsername());
TextView text = (TextView) view.findViewById(R.id.account_info_text);
text.setText(Html.fromHtml(
String.format(getString(R.string.account_info_text),
user.getFirstname(),
user.getLastname(),
user.getUsername(),
device,
expire,
user.getLevel(),
user.getGrade()
)
));
Button logoutbtn = (Button) view.findViewById(R.id.logout_button);
logoutbtn.setOnClickListener(new View.OnClickListener() {
......@@ -76,6 +103,8 @@ public class AccountFragment extends Fragment {
}
});
updateAdditionalClasses();
return view;
}
......@@ -95,4 +124,155 @@ public class AccountFragment extends Fragment {
i.setData(Uri.parse(url));
startActivity(i);
}
private void showDialog(List<String> classes, List<String> preselect, final int max) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Set the dialog title
builder.setTitle(R.string.account_additional_title);
final String[] class_arr = new String[classes.size()];
int x = 0;
for (String str : classes) {
class_arr[x] = str;
x++;
}
final boolean[] selected = new boolean[class_arr.length];
for (int i = 0; i < class_arr.length; ++i) {
if (preselect.contains(class_arr[i])) {
selected[i] = true;
}
}
builder.setMultiChoiceItems(class_arr, selected, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i, boolean b) {
if (b) {
selected[i] = true;
if (max >= 0) {
int count = 0;
for (boolean bool : selected) {
if (bool) {
count++;
}
}
if (count > max) {
selected[i] = false;
((AlertDialog) dialogInterface).getListView().setItemChecked(i, false);
}
}
} else {
selected[i] = false;
}
}
});
builder.setPositiveButton(R.string.account_accept, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
List<String> cls = new LinkedList<>();
for (int j = 0; j < class_arr.length; ++j) {
if (selected[j]) {
cls.add(class_arr[j]);
}
}
MyTFGApi api = new MyTFGApi(context);
api.setAdditionalClasses(cls);
dialogInterface.dismiss();
updateAdditionalClasses();
}
});
builder.setNegativeButton(R.string.account_discard, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
builder.show();
}
private void updateAdditionalClasses() {
MyTFGApi api = new MyTFGApi(context);
final User user = api.getUser();
// Additional classes
TextView explanation = (TextView)view.findViewById(R.id.account_additional_explanation);
TextView additional = (TextView)view.findViewById(R.id.account_additional_classes);
Button selectBtn = (Button)view.findViewById(R.id.account_additional_button);
String additionals = TextUtils.join(", ", api.getAdditionalClasses());
if (api.getAdditionalClasses().size() == 0) {
additionals = getString(R.string.account_addional_classes_none);
}
switch (user.getRights()) {
case 1:
explanation.setText(Html.fromHtml(
String.format(getString(R.string.account_additional_explanation_pupil),
user.getGrade())
));
selectBtn.setVisibility(View.VISIBLE);
additional.setText(Html.fromHtml(
String.format(getString(R.string.account_addional_classes),
additionals
)
));
break;
case 2:
explanation.setText(Html.fromHtml(
getString(R.string.account_additional_explanation_pupil)
));
selectBtn.setVisibility(View.VISIBLE);
additional.setText(Html.fromHtml(
String.format(getString(R.string.account_addional_classes),
additionals
)
));
break;
default:
explanation.setText(Html.fromHtml(
String.format(getString(R.string.account_additional_explanation_pupil),
user.getLevel())
));
break;
}
selectBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final ProgressDialog dialog = ProgressDialog.show(view.getContext(),
getString(R.string.please_wait),
getString(R.string.account_process),
true);
final MyTFGApi api = new MyTFGApi(context);
ApiParams params = new ApiParams();
api.addAuth(params);
api.call("api_vplan_classes", params, new ApiCallback() {
@Override
public void callback(JSONObject result, int responseCode) {
dialog.dismiss();
if (responseCode == HttpsURLConnection.HTTP_OK) {
List<String> classes = new LinkedList<>();
try {
JSONArray extra_classes = result.getJSONArray("extra_classes");
String ownClass = user.getGrade().toLowerCase();
for (int i = 0; i < extra_classes.length(); ++i) {
if (!extra_classes.get(i).toString().toLowerCase().equals(ownClass)) {
classes.add(extra_classes.get(i).toString());
}
}
showDialog(classes, api.getAdditionalClasses(), user.getRights() == 1 ? 3 : -1);
} catch (JSONException ex) {
CoordinatorLayout coordinatorLayout = context.getToolbarManager().coordinatorLayout();
Snackbar snackbar = Snackbar
.make(coordinatorLayout,
getString(R.string.api_response),
Snackbar.LENGTH_LONG);
snackbar.show();
}
} else {
CoordinatorLayout coordinatorLayout = context.getToolbarManager().coordinatorLayout();
Snackbar snackbar = Snackbar
.make(coordinatorLayout,
getString(R.string.api_serverfault),
Snackbar.LENGTH_LONG);
snackbar.show();
}
}
});
}
});
}
}
......@@ -10,7 +10,6 @@ import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
......@@ -184,9 +183,6 @@ public class PlanFragment extends Fragment {
today = new PlanLogic(todayPlan);
tomorrow = new PlanLogic(tomorrowPlan);
Log.d("onResume", "Called on Resume");
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(this.getChildFragmentManager());
viewPagerAdapter.addFragment(
......
package de.mytfg.apps.vplan.objects;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
......@@ -76,6 +77,7 @@ public class Vplan extends MytfgObject {
MyTFGApi api = new MyTFGApi(context);
ApiParams params = new ApiParams();
params.addParam("day", this.day);
params.addParam("additionals", TextUtils.join(",", api.getAdditionalClasses()));
api.addAuth(params);
api.call("api_vplan_get", params, new ApiCallback() {
@Override
......@@ -115,10 +117,17 @@ public class Vplan extends MytfgObject {
JSONArray entries = plan.getJSONArray("entries");
for (int i = 0; i < entries.length(); ++i) {
VplanEntry vplanEntry = new VplanEntry();
VplanEntry vplanEntry = new VplanEntry(true);
vplanEntry.load(this, entries.getJSONObject(i));
this.entries.add(vplanEntry);
}
JSONArray additionals = plan.getJSONArray("additional_entries");
for (int i = 0; i < additionals.length(); ++i) {
VplanEntry vplanEntry = new VplanEntry(false);
vplanEntry.load(this, additionals.getJSONObject(i));
this.entries.add(vplanEntry);
}
JSONArray marquee = plan.getJSONArray("marquee");
for (int i = 0; i < marquee.length(); ++i) {
this.marquee.add(marquee.getString(i));
......
......@@ -17,7 +17,14 @@ public class VplanEntry extends MytfgObject {
private String comment;
private String teacher;
private boolean own;
private Vplan day;
public VplanEntry(boolean own) {
this.own = own;
}
/**
* Loading is done locally. Use <code>load(JSONObject data)</code> instead.
* @param callback Called when loading finished.
......@@ -88,4 +95,8 @@ public class VplanEntry extends MytfgObject {
|| getPlan().toLowerCase().contains(filter)
|| getSubstitution().toLowerCase().contains(filter);
}
public boolean isOwn() {
return own;
}
}
......@@ -2,14 +2,14 @@
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@color/colorPrimaryLight"
android:layout_height="wrap_content"
android:padding="10dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:padding="10dp"
android:background="@color/colorPrimaryLight">
android:padding="10dp">
<LinearLayout
android:layout_width="120dp"
......
......@@ -34,32 +34,60 @@
android:textSize="@dimen/textDefault"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/account_info"
android:id="@+id/account_info" />
android:text="@string/account_info_text"
android:id="@+id/account_info_text" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:id="@+id/logout_button"
android:text="@string/logout_action"
style="@style/AppTheme.Button"/>
</LinearLayout>
</android.support.v7.widget.CardView>
<!-- -->
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="@dimen/cardview_spacing"
android:layout_marginBottom="@dimen/defaultPadding">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/cardview_spacing"
android:background="@color/colorPrimaryLight">
<TextView
android:textSize="@dimen/textDefault"
android:textSize="@dimen/textTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/account_info_username"
android:text="@string/account_info_username" />
android:text="@string/account_additional_title"
android:id="@+id/account_additional_title"/>
<TextView
android:textSize="@dimen/textDefault"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/account_info_device"
android:text="@string/account_info_device" />
android:id="@+id/account_additional_explanation"/>
<TextView
android:textSize="@dimen/textDefault"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/account_info_expire"
android:text="@string/account_info_expire" />
android:id="@+id/account_additional_classes"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:id="@+id/logout_button"
android:text="@string/logout_action"
android:id="@+id/account_additional_button"
android:visibility="gone"
android:text="@string/account_additional_select"
style="@style/AppTheme.Button"/>
</LinearLayout>
......
......@@ -19,6 +19,7 @@
<string name="api_offline">Keine Internet Verbindung</string>
<string name="api_noauth">Keine Berechtigung</string>
<string name="api_serverfault">Interner Server Fehler</string>
<string name="api_response">Ungültige Server Antwort</string>
<!-- LOGIN -->
<string name="login_text">Um diese App und all ihre Funktionen nutzen zu können,
......@@ -67,12 +68,37 @@
<string name="plan_search">Suchen</string>
<!-- ACCOUNT -->
<string name="account_info">Sie sind angemeldet.</string>
<string name="account_info_username"><b>Nutzername</b>: %1$s</string>
<string name="account_info_device"><b>Geräte-ID</b>: %1$s</string>
<string name="account_info_expire">Ihr Login ist gültig bis %1$s</string>
<string name="account_info_text">
Hallo, &lt;b>%1$s %2$s&lt;/b>!&lt;br/>
Sie sind angemeldet.&lt;br/>
Ihr Nutzername ist &lt;b>%3$s&lt;/b>&lt;br/>
Die Geräte-ID ist &lt;b>%4$s&lt;/b>&lt;br/>
Ihre Anmeldung ist gültig bis %5$s&lt;br/>
Ihr Berechtigungslevel ist &lt;b>%6$s&lt;/b>&lt;br/>
Ihre Klasse ist &lt;b>%7$s&lt;/b>
</string>
<string name="logout_action">Abmelden</string>
<string name="account_logged_out">Sie wurden ausgeloggt</string>
<string name="account_additional_title">Zusätzliche Klassen</string>
<string name="account_additional_select">Weitere Klassen wählen</string>
<string name="account_additional_explanation_pupil">
Als Schüler der Klasse &lt;b>%1$s&lt;/b> erhalten Sie alle Einträge, die Ihre Klasse betreffen.&lt;br/>
Sie haben die Möglichkeit, &lt;b>3&lt;/b> weitere Klassen hinzuzufügen, für die Sie Einträge angezeigt bekommen möchten.
</string>
<string name="account_additional_explanation_teacher">
Als Lehrer erhalten Sie alle Einträge, welche Sie betreffen.&lt;br/>
Sie haben die Möglichkeit, verschiedene Klassen hinzuzufügen, für die Sie ebenfalls Einträge erhalten wollen.
</string>
<string name="account_additional_explanation_highlevel">
Als %1$s erhalten Sie alle Einträge der Vertretungsplans.&lt;br/>
Somit können Sie keine zusätzlichen Klassen wählen.
</string>
<string name="account_addional_classes">&lt;b>Zusätzliche Klassen&lt;/b>&lt;br/>%1$s</string>
<string name="account_addional_classes_none">&lt;i>Keine zusätzlichen Klassen ausgewählt&lt;/i></string>
<string name="account_process">Zusätzliche Klassen werden geladen</string>
<string name="account_accept">Speichern</string>
<string name="account_discard">Verwerfen</string>
<!-- USER -->
<string name="user_rights_norights">Nicht eingeloggt</string>
......
......@@ -3,6 +3,7 @@
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorPrimaryLight">#C5CAE9</color>
<color name="colorSecondaryLight">#DFE2F4</color>
<color name="colorIcons">#FFFFFF</color>
<color name="colorPrimaryText">#212121</color>
<color name="colorSecondaryText">#DDDDDD</color>
......
......@@ -52,6 +52,7 @@
<string name="api_offline">No Internet connection</string>
<string name="api_noauth">No permissions to request the content</string>
<string name="api_serverfault">Internal Server error</string>
<string name="api_response">Invalid Server response</string>
<!-- LOGIN -->
<string name="login_text">To use this App and all its features you have to login first.</string>
......@@ -66,12 +67,36 @@
<string name="login_serverfault">Server error</string>
<!-- ACCOUNT -->
<string name="account_info">You are currently logged in.</string>
<string name="account_info_username"><b>Username</b>: %1$s</string>
<string name="account_info_device"><b>Device-Id</b>: %1$s</string>
<string name="account_info_expire">Your login will expire at %1$s</string>
<string name="account_info_text">
Hello, &lt;b>%1$s %2$s&lt;/b>&lt;br/>
You are currently logged in.&lt;br/>
Your username is &lt;b>%3$s&lt;/b>&lt;br/>
The device ID is &lt;b>%4$s&lt;/b>&lt;br/>
Your login will expire at %5$s&lt;br/>
Your user level is &lt;b>%6$s&lt;/b>&lt;br/>
Your class is &lt;b>%7$s&lt;/b>
</string>
<string name="logout_action">Logout</string>
<string name="account_logged_out">You were logged out</string>
<string name="account_additional_title">Additional classes</string>
<string name="account_additional_select">Select additional classes</string>
<string name="account_additional_explanation_pupil">