Even more CardView and new Semester Class, updated Module List
This commit is contained in:
@@ -537,7 +537,7 @@ public class MainActivity extends AppCompatActivity
|
||||
|
||||
@Override
|
||||
public void onLogin(LoginToken token, boolean enteringOnlineMode) {
|
||||
toLoginState(token.getUsername(), token.getEmail(), getDefaultFragmentAfterLogin(), enteringOnlineMode);
|
||||
toLoginState(token.getFullName(), token.getEmail(), getDefaultFragmentAfterLogin(), enteringOnlineMode);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,66 +1,115 @@
|
||||
package de.sebse.fuplanner.fragments;
|
||||
|
||||
import android.util.Pair;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.fragments.ModulesFragment.OnModulesFragmentInteractionListener;
|
||||
import de.sebse.fuplanner.services.KVV.types.Lecturer;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.services.KVV.types.Semester;
|
||||
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.ItemViewHolder;
|
||||
import de.sebse.fuplanner.tools.ui.StringViewHolder;
|
||||
|
||||
/**
|
||||
* {@link RecyclerView.Adapter} that can display a {@link Modules.Module} and makes a call to the
|
||||
* specified {@link OnModulesFragmentInteractionListener}.
|
||||
*/
|
||||
class ModulesAdapter extends RecyclerView.Adapter<ItemViewHolder> {
|
||||
class ModulesAdapter extends RecyclerView.Adapter<CustomViewHolder> {
|
||||
|
||||
private static final int TYPE_HEADER = 0;
|
||||
private static final int TYPE_ITEM = 2;
|
||||
|
||||
private Modules mValues;
|
||||
private final OnModulesFragmentInteractionListener mListener;
|
||||
private final ArrayList<Pair<Integer, Object>> mPositionalData;
|
||||
|
||||
ModulesAdapter(OnModulesFragmentInteractionListener listener) {
|
||||
mValues = null;
|
||||
mListener = listener;
|
||||
mPositionalData = new ArrayList<>();
|
||||
}
|
||||
|
||||
public void setModules(Modules modules) {
|
||||
mValues = modules;
|
||||
mPositionalData.clear();
|
||||
Semester lastSemester = null;
|
||||
for (Modules.Module module : mValues) {
|
||||
Semester semester = module.semester;
|
||||
if (semester == null)
|
||||
continue;
|
||||
if (!semester.equals(lastSemester)) {
|
||||
mPositionalData.add(new Pair<>(TYPE_HEADER, semester));
|
||||
lastSemester = semester;
|
||||
}
|
||||
mPositionalData.add(new Pair<>(TYPE_ITEM, module));
|
||||
}
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
return mPositionalData.get(position).first;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_items, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
if (viewType == TYPE_HEADER) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_caption, parent, false);
|
||||
return new StringViewHolder(view);
|
||||
} else {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_items, parent, false);
|
||||
return new ItemViewHolder(view);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) {
|
||||
if (mValues == null)
|
||||
return;
|
||||
Modules.Module module = mValues.getByIndex(holder.getAdapterPosition());
|
||||
holder.mTitle.setText(module.title);
|
||||
holder.mSubLeft.setText(module.semester);
|
||||
holder.mSubRight.setText(module.type);
|
||||
|
||||
holder.mView.setOnClickListener(v -> {
|
||||
if (null != mListener) {
|
||||
// Notify the active callbacks interface (the activity, if the
|
||||
// fragment is attached to one) that an item has been selected.
|
||||
mListener.onModulesFragmentInteraction(module.getID());
|
||||
public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
|
||||
Pair<Integer, Object> pair = mPositionalData.get(holder.getAdapterPosition());
|
||||
if (pair.first == TYPE_HEADER) {
|
||||
StringViewHolder sHolder = (StringViewHolder) holder;
|
||||
String localizedSemester;
|
||||
Semester semester = (Semester) pair.second;
|
||||
if (semester.getType() == Semester.SEM_WS)
|
||||
localizedSemester = holder.mView.getResources().getString(R.string.winter_semester, semester.getYear(), semester.getYear()+1);
|
||||
else
|
||||
localizedSemester = holder.mView.getResources().getString(R.string.summer_semester, semester.getYear());
|
||||
sHolder.mString.setText(localizedSemester);
|
||||
} else if (pair.first == TYPE_ITEM) {
|
||||
ItemViewHolder iHolder = (ItemViewHolder) holder;
|
||||
Modules.Module module = ((Modules.Module) pair.second);
|
||||
iHolder.mTitle.setText(module.title);
|
||||
StringBuilder lecturers = new StringBuilder();
|
||||
for (Lecturer lecturer : module.lecturer) {
|
||||
if (!lecturer.isResponsible())
|
||||
continue;
|
||||
if (lecturers.length() > 0)
|
||||
lecturers.append(", ");
|
||||
lecturers.append(lecturer.getNameShort());
|
||||
}
|
||||
});
|
||||
iHolder.mSubLeft.setText(lecturers);
|
||||
iHolder.mSubRight.setText(module.type);
|
||||
|
||||
iHolder.mView.setOnClickListener(v -> {
|
||||
if (mListener != null) {
|
||||
mListener.onModulesFragmentInteraction(module.getID());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mValues != null) {
|
||||
return mValues.size();
|
||||
}
|
||||
return 0;
|
||||
return mPositionalData.size();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.regex.MatchResult;
|
||||
|
||||
import de.sebse.fuplanner.services.KVV.types.Lecturer;
|
||||
import de.sebse.fuplanner.services.KVV.types.Modules;
|
||||
import de.sebse.fuplanner.services.KVV.types.Semester;
|
||||
import de.sebse.fuplanner.tools.NewAsyncQueue;
|
||||
import de.sebse.fuplanner.tools.Regex;
|
||||
import de.sebse.fuplanner.tools.network.HTTPService;
|
||||
@@ -157,7 +158,8 @@ public class ModulesList extends HTTPService {
|
||||
for (int i = 0; i < sites.length(); i++) {
|
||||
try {
|
||||
JSONObject site = sites.getJSONObject(i);
|
||||
String semester = site.getJSONObject("props").optString("term_eid", null);
|
||||
String semester_string = site.getJSONObject("props").optString("term_eid", null);
|
||||
Semester semester = new Semester(semester_string);
|
||||
HashSet<String> lvNumbers = new HashSet<>();
|
||||
String kvv_lvnumbers = site.getJSONObject("props").optString("kvv_lvnumbers", null);
|
||||
if (kvv_lvnumbers != null) for (MatchResult matchResult : Regex.allMatches("[0-9]+", kvv_lvnumbers)) {
|
||||
|
||||
@@ -4,13 +4,16 @@ import java.io.Serializable;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
|
||||
public class Lecturer implements Serializable {
|
||||
private final String firstName;
|
||||
private final String surname;
|
||||
private final String mail;
|
||||
private final boolean isResponsible;
|
||||
|
||||
public Lecturer(String parsableString) throws NoSuchFieldException {
|
||||
Pattern pattern = Pattern.compile("([^|]*)\\|([^|]*)\\|([^|]*)\\|\\|", Pattern.DOTALL);
|
||||
Pattern pattern = Pattern.compile("([^|]*)\\|([^|]*)\\|([^|]*)\\|\\|([^|]*)", Pattern.DOTALL);
|
||||
Matcher matcher = pattern.matcher(parsableString);
|
||||
if (!matcher.find()) {
|
||||
throw new NoSuchFieldException();
|
||||
@@ -18,20 +21,33 @@ public class Lecturer implements Serializable {
|
||||
this.firstName = matcher.group(1);
|
||||
this.surname = matcher.group(2);
|
||||
this.mail = matcher.group(3);
|
||||
this.isResponsible = matcher.group(4).equals("true");
|
||||
}
|
||||
|
||||
private String getFirstName() {
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
private String getSurname() {
|
||||
public String getSurname() {
|
||||
return surname;
|
||||
}
|
||||
|
||||
private String getMail() {
|
||||
public String getMail() {
|
||||
return mail;
|
||||
}
|
||||
|
||||
public boolean isResponsible() {
|
||||
return isResponsible;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return getFirstName() + " " + getSurname();
|
||||
}
|
||||
|
||||
public String getNameShort() {
|
||||
return getFirstName().substring(0, 1) + ". " + getSurname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "First name: "+ getFirstName()+
|
||||
|
||||
@@ -10,6 +10,7 @@ import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
@@ -32,7 +33,7 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
this.list = new SortedListModule();
|
||||
}
|
||||
|
||||
public void addModule(@Nullable String semester, HashSet<String> lvNumber, String title, HashSet<Lecturer> lecturer, String type, String description, String ID) {
|
||||
public void addModule(@Nullable Semester semester, HashSet<String> lvNumber, String title, HashSet<Lecturer> lecturer, String type, String description, String ID) {
|
||||
Module m = new Module(semester, lvNumber, title, lecturer, type, description, ID);
|
||||
this.list.add(m);
|
||||
}
|
||||
@@ -109,10 +110,11 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
}
|
||||
|
||||
public class Module implements Serializable {
|
||||
@Nullable public final String semester;
|
||||
@Nullable public final Semester semester;
|
||||
@NotNull final HashSet<String> lvNumber;
|
||||
@NotNull public final String title;
|
||||
@NotNull final HashSet<Lecturer> lecturer;
|
||||
@NotNull
|
||||
public final HashSet<Lecturer> lecturer;
|
||||
@Nullable public final String type;
|
||||
@Nullable public final String description;
|
||||
@NotNull private final String ID;
|
||||
@@ -136,11 +138,8 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
||||
return userPoint/maxPoint;
|
||||
}
|
||||
|
||||
private Module(@Nullable String semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull HashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID) {
|
||||
if (semester != null) {
|
||||
semester = semester.replace("SS", "S");
|
||||
semester = semester.replaceAll("[0-9]{2}([0-9]{2})", "$1");
|
||||
}
|
||||
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull HashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID) {
|
||||
|
||||
title = title.replaceAll("(.*?) (S[0-9]{2}|W[0-9/]{5})", "$1");
|
||||
|
||||
this.semester = semester;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package de.sebse.fuplanner.services.KVV.types;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import de.sebse.fuplanner.tools.Regex;
|
||||
|
||||
public class Semester {
|
||||
public static final int SEM_WS = 1;
|
||||
public static final int SEM_SS = 2;
|
||||
private int type;
|
||||
private int year;
|
||||
|
||||
public Semester(int type, int year) {
|
||||
this.type = type;
|
||||
this.year = year;
|
||||
}
|
||||
|
||||
public Semester(String semester_string) throws NoSuchFieldException {
|
||||
/*Semester sem = null;
|
||||
if (semester != null) {
|
||||
sem = new Semester(semester)
|
||||
semester = semester.replace("SS", "S");
|
||||
semester = semester.replaceAll("[0-9]{2}([0-9]{2})", "$1");
|
||||
}*/
|
||||
|
||||
|
||||
/*String s1type = Regex.regex("^(S|WS) ", a);
|
||||
int s1year = Integer.parseInt(Regex.regex("^(S|WS) ([0-9]{2})", a, 2));
|
||||
String s2type = Regex.regex("^(S|WS) ", b);
|
||||
int s2year = Integer.parseInt(Regex.regex("^(S|WS) ([0-9]{2})", b, 2));*/
|
||||
|
||||
String type = Regex.regex("^(SS|WS) ", semester_string);
|
||||
String year = Regex.regex("^(SS|WS) ([0-9]{2})", semester_string, 2);
|
||||
this.type = type.equals("SS") ? SEM_SS : SEM_WS;
|
||||
this.year = Integer.parseInt(year);
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getYear() {
|
||||
return year;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object obj) {
|
||||
if (obj instanceof Semester) {
|
||||
Semester other = (Semester) obj;
|
||||
return other.type == type && other.year == year;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
package de.sebse.fuplanner.services.KVV.types;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import de.sebse.fuplanner.tools.Regex;
|
||||
import de.sebse.fuplanner.tools.SortedList;
|
||||
|
||||
public class SortedListModule extends SortedList<Modules.Module, String, String> {
|
||||
public class SortedListModule extends SortedList<Modules.Module, String, Semester> {
|
||||
private static final int LARGER = 1;
|
||||
private static final int EQUAL = 0;
|
||||
private static final int SMALLER = -1;
|
||||
@@ -27,7 +28,7 @@ public class SortedListModule extends SortedList<Modules.Module, String, String>
|
||||
super.add(e);
|
||||
}
|
||||
|
||||
public String getLatestSemester() {
|
||||
public Semester getLatestSemester() {
|
||||
if (size() > 0)
|
||||
//noinspection ConstantConditions
|
||||
return this.get(0).semester;
|
||||
@@ -35,7 +36,7 @@ public class SortedListModule extends SortedList<Modules.Module, String, String>
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int compareSemester(String a, String b) throws NoSuchFieldException {
|
||||
private static int compareSemester(@Nullable Semester a, @Nullable Semester b) throws NoSuchFieldException {
|
||||
if (a == null && b == null)
|
||||
return EQUAL;
|
||||
if (a == null)
|
||||
@@ -43,17 +44,13 @@ public class SortedListModule extends SortedList<Modules.Module, String, String>
|
||||
if (b == null)
|
||||
return LARGER;
|
||||
|
||||
String s1type = Regex.regex("^(S|WS) ", a);
|
||||
int s1year = Integer.parseInt(Regex.regex("^(S|WS) ([0-9]{2})", a, 2));
|
||||
String s2type = Regex.regex("^(S|WS) ", b);
|
||||
int s2year = Integer.parseInt(Regex.regex("^(S|WS) ([0-9]{2})", b, 2));
|
||||
|
||||
if (s1year == s2year) {
|
||||
if (s1type.equals(s2type))
|
||||
if (a.getYear() == b.getYear()) {
|
||||
if (a.getType() == b.getType())
|
||||
return EQUAL;
|
||||
return s1type.equals("S") ? SMALLER : LARGER;
|
||||
return a.getType() == Semester.SEM_SS ? SMALLER : LARGER;
|
||||
}
|
||||
return s1year < s2year ? SMALLER : LARGER;
|
||||
return a.getYear() < b.getYear() ? SMALLER : LARGER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +59,7 @@ public class SortedListModule extends SortedList<Modules.Module, String, String>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasFilter(Modules.Module o1, String filter) {
|
||||
public boolean hasFilter(Modules.Module o1, Semester filter) {
|
||||
return o1.semester != null && o1.semester.equals(filter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_margin="4dp">
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:typeface="sans"
|
||||
tools:text="Test this new stuff!" />
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:typeface="sans"
|
||||
tools:text="Test this new stuff!" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sub_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="5dip"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
tools:text="Peter Bauer" />
|
||||
<TextView
|
||||
android:id="@+id/sub_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="5dip"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
tools:text="Peter Bauer" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sub_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/sub_left"
|
||||
android:layout_alignBottom="@id/sub_left"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
tools:text="20.03.18 18:42 Uhr" />
|
||||
<TextView
|
||||
android:id="@+id/sub_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/sub_left"
|
||||
android:layout_alignBottom="@id/sub_left"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
tools:text="20.03.18 18:42 Uhr" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/top_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/title"
|
||||
android:layout_alignBottom="@id/title"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
tools:text="Room 105"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
</RelativeLayout>
|
||||
<TextView
|
||||
android:id="@+id/top_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@id/title"
|
||||
android:layout_alignBottom="@id/title"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
tools:text="Room 105"
|
||||
tools:ignore="RelativeOverlap" />
|
||||
</RelativeLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
@@ -76,4 +76,6 @@
|
||||
<string name="exam">Klausur</string>
|
||||
<string name="other">Andere</string>
|
||||
<string name="deadline">Abgabe</string>
|
||||
<string name="winter_semester">Wintersemester %1$d/%2$d</string>
|
||||
<string name="summer_semester">Sommersemester %1$d</string>
|
||||
</resources>
|
||||
@@ -84,4 +84,6 @@
|
||||
<string name="exam">Exam</string>
|
||||
<string name="other">Other</string>
|
||||
<string name="deadline">Deadline</string>
|
||||
<string name="winter_semester">Winter Semester %1$d/%2$d</string>
|
||||
<string name="summer_semester">Summer Semester %1$d</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user