Gradebook Design Update
This commit is contained in:
@@ -13,6 +13,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import de.sebse.fuplanner.R;
|
import de.sebse.fuplanner.R;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||||
|
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||||
import de.sebse.fuplanner.tools.ui.StringViewHolder;
|
import de.sebse.fuplanner.tools.ui.StringViewHolder;
|
||||||
|
|
||||||
@@ -20,9 +21,12 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
private static final int TYPE_TOTAL = 0;
|
private static final int TYPE_TOTAL = 0;
|
||||||
private static final int TYPE_GRADE = 1;
|
private static final int TYPE_GRADE = 1;
|
||||||
|
|
||||||
private static final int SECTION_GRADE = 0;
|
private static final int SECTION_EXAM = 0;
|
||||||
|
private static final int SECTION_ASSIGNMENT = 1;
|
||||||
|
private static final int SECTION_OTHER = 2;
|
||||||
|
|
||||||
private Modules.Module mValue;
|
private Modules.Module mValue;
|
||||||
|
private Gradebook.CategorizedGrades mGrades;
|
||||||
private final ArrayList<Pair<Integer, Integer>> mPositionalData;
|
private final ArrayList<Pair<Integer, Integer>> mPositionalData;
|
||||||
|
|
||||||
ModDetailGradebookAdapter() {
|
ModDetailGradebookAdapter() {
|
||||||
@@ -38,9 +42,32 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
|
|
||||||
private void setModule() {
|
private void setModule() {
|
||||||
mPositionalData.clear();
|
mPositionalData.clear();
|
||||||
mPositionalData.add(new Pair<>(TYPE_TOTAL, SECTION_GRADE));
|
if (mValue != null && mValue.gradebook != null) {
|
||||||
for (int i = 0; i < getGradesCount(); i++) {
|
mGrades = mValue.gradebook.getAutoCategorizedGrades();
|
||||||
mPositionalData.add(new Pair<>(TYPE_GRADE, SECTION_GRADE +1024*i));
|
int size;
|
||||||
|
size = mGrades.getExams().grades.size();
|
||||||
|
if (size > 0) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_EXAM), 0));
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_EXAM), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = mGrades.getAssignments().grades.size();
|
||||||
|
if (size > 0) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_ASSIGNMENT), 0));
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_ASSIGNMENT), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = mGrades.getOthers().grades.size();
|
||||||
|
if (size > 0) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_TOTAL, SECTION_OTHER), 0));
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
mPositionalData.add(new Pair<>(setViewType(TYPE_GRADE, SECTION_OTHER), i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mGrades = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.notifyDataSetChanged();
|
this.notifyDataSetChanged();
|
||||||
@@ -53,8 +80,8 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
case TYPE_TOTAL:
|
case TYPE_TOTAL:
|
||||||
view = LayoutInflater.from(parent.getContext())
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_all_caption, parent, false);
|
.inflate(R.layout.list_moddetails_gradebook_title, parent, false);
|
||||||
return new StringViewHolder(view);
|
return new GradeTitleViewHolder(view);
|
||||||
case TYPE_GRADE:
|
case TYPE_GRADE:
|
||||||
view = LayoutInflater.from(parent.getContext())
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_moddetails_gradebook, parent, false);
|
.inflate(R.layout.list_moddetails_gradebook, parent, false);
|
||||||
@@ -69,7 +96,7 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
public int getItemViewType(int position) {
|
public int getItemViewType(int position) {
|
||||||
// Note that unlike in ListView adapters, types don't have to be contiguous
|
// Note that unlike in ListView adapters, types don't have to be contiguous
|
||||||
if (position < mPositionalData.size())
|
if (position < mPositionalData.size())
|
||||||
return mPositionalData.get(position).first;
|
return getViewType(mPositionalData.get(position).first);
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,19 +106,45 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
if (mValue == null || position > mPositionalData.size())
|
if (mValue == null || position > mPositionalData.size())
|
||||||
return;
|
return;
|
||||||
Pair<Integer, Integer> data = mPositionalData.get(position);
|
Pair<Integer, Integer> data = mPositionalData.get(position);
|
||||||
switch (data.first) {
|
int viewType = getViewType(data.first);
|
||||||
|
int viewSection = getViewSection(data.first);
|
||||||
|
Gradebook.GradebookOutput gradebook = getViewSectionGradebook(viewSection);
|
||||||
|
switch (viewType) {
|
||||||
case TYPE_TOTAL:
|
case TYPE_TOTAL:
|
||||||
StringViewHolder h = (StringViewHolder) holder;
|
GradeTitleViewHolder h = (GradeTitleViewHolder) holder;
|
||||||
h.mString.setText(h.mView.getResources().getString(R.string.current_percentage, mValue.getGradebookPercent()*100));
|
|
||||||
|
if (gradebook != null) {
|
||||||
|
String title = "";
|
||||||
|
switch (viewSection) {
|
||||||
|
case SECTION_EXAM: title = h.mView.getResources().getString(R.string.exam); break;
|
||||||
|
case SECTION_ASSIGNMENT: title = h.mView.getResources().getString(R.string.assignments); break;
|
||||||
|
case SECTION_OTHER: title = h.mView.getResources().getString(R.string.others); break;
|
||||||
|
}
|
||||||
|
h.mTitle.setText(title);
|
||||||
|
Grade bestGrade = gradebook.getBestGrade();
|
||||||
|
h.mString.setText(h.mView.getResources().getString(
|
||||||
|
R.string.current_percentage,
|
||||||
|
gradebook.getUserPointSum(),
|
||||||
|
gradebook.getMaxPointSum(),
|
||||||
|
gradebook.getPercentage() * 100,
|
||||||
|
bestGrade.getPoints(),
|
||||||
|
bestGrade.getMaxPoints(),
|
||||||
|
bestGrade.getPoints() / bestGrade.getMaxPoints() * 100,
|
||||||
|
bestGrade.getItemName()
|
||||||
|
));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TYPE_GRADE:
|
case TYPE_GRADE:
|
||||||
int index = data.second / 1024;
|
int index = data.second;
|
||||||
GradeViewHolder i = (GradeViewHolder) holder;
|
GradeViewHolder i = (GradeViewHolder) holder;
|
||||||
Grade gradebook = mValue.gradebook.get(index);
|
|
||||||
|
|
||||||
i.mTitle.setText(gradebook.getItemName());
|
if (gradebook != null) {
|
||||||
i.mGrade.setText(String.valueOf(gradebook.getPoints()));
|
Grade grade = gradebook.grades.get(index);
|
||||||
i.mGradeMax.setText(String.valueOf(gradebook.getMaxPoints()));
|
|
||||||
|
i.mTitle.setText(grade.getItemName());
|
||||||
|
i.mGrade.setText(String.valueOf(grade.getPoints()));
|
||||||
|
i.mGradeMax.setText(String.valueOf(grade.getMaxPoints()));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,10 +154,27 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
return mPositionalData.size();
|
return mPositionalData.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getGradesCount() {
|
private int setViewType(int type, int section) {
|
||||||
if (mValue.gradebook != null)
|
return type * 1024 + section;
|
||||||
return mValue.gradebook.size();
|
}
|
||||||
return 0;
|
|
||||||
|
private int getViewType(int combinedViewType) {
|
||||||
|
return combinedViewType / 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getViewSection(int combinedViewType) {
|
||||||
|
return combinedViewType - getViewType(combinedViewType) * 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Gradebook.GradebookOutput getViewSectionGradebook(int viewSection) {
|
||||||
|
if (mGrades != null) {
|
||||||
|
switch (viewSection) {
|
||||||
|
case SECTION_EXAM: return mGrades.getExams();
|
||||||
|
case SECTION_ASSIGNMENT: return mGrades.getAssignments();
|
||||||
|
case SECTION_OTHER: return mGrades.getOthers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -133,4 +203,19 @@ class ModDetailGradebookAdapter extends RecyclerView.Adapter<RecyclerView.ViewHo
|
|||||||
return super.toString() + " '" + mTitle.getText() + " '" + mGrade.getText() + " '" + mGradeMax.getText() + "'";
|
return super.toString() + " '" + mTitle.getText() + " '" + mGrade.getText() + " '" + mGradeMax.getText() + "'";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class GradeTitleViewHolder extends StringViewHolder {
|
||||||
|
private final TextView mTitle;
|
||||||
|
|
||||||
|
GradeTitleViewHolder(View view) {
|
||||||
|
super(view);
|
||||||
|
mTitle = view.findViewById(R.id.title);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return super.toString() + " '" + mTitle.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,31 +9,32 @@ import org.json.JSONObject;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||||
|
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||||
|
|
||||||
public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
public class ModulesGradebook extends PartModules<Gradebook> {
|
||||||
|
|
||||||
ModulesGradebook(Login login, ModulesList list, Context context) {
|
ModulesGradebook(Login login, ModulesList list, Context context) {
|
||||||
super(login, list, context);
|
super(login, list, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ArrayList<Grade> getPart(Modules.Module module) {
|
protected Gradebook getPart(Modules.Module module) {
|
||||||
return module.gradebook;
|
return module.gradebook;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean setPart(Modules.Module module, ArrayList<Grade> part) {
|
protected boolean setPart(Modules.Module module, Gradebook part) {
|
||||||
boolean changed = module.gradebook == null || module.gradebook.hashCode() != part.hashCode();
|
boolean changed = module.gradebook == null || module.gradebook.hashCode() != part.hashCode();
|
||||||
module.gradebook = part;
|
module.gradebook = part;
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void upgradeKVV(final String ID, final NetworkCallback<ArrayList<Grade>> callback, final NetworkErrorCallback errorCallback) {
|
protected void upgradeKVV(final String ID, final NetworkCallback<Gradebook> callback, final NetworkErrorCallback errorCallback) {
|
||||||
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null || !mLogin.getLoginTokenKVV().isAvailable()) {
|
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenKVV() == null || !mLogin.getLoginTokenKVV().isAvailable()) {
|
||||||
errorCallback.onError(new NetworkError(101504, 500, "Currently running in offline mode!"));
|
errorCallback.onError(new NetworkError(101504, 500, "Currently running in offline mode!"));
|
||||||
return;
|
return;
|
||||||
@@ -44,7 +45,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
errorCallback.onError(new NetworkError(101501, 403, "No gradebook retrieved!"));
|
errorCallback.onError(new NetworkError(101501, 403, "No gradebook retrieved!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList<Grade> gradebook = new ArrayList<>();
|
Gradebook gradebook = new Gradebook();
|
||||||
JSONArray sites;
|
JSONArray sites;
|
||||||
try {
|
try {
|
||||||
JSONObject json = new JSONObject(body);
|
JSONObject json = new JSONObject(body);
|
||||||
@@ -62,7 +63,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
String itemName = site.optString("itemName", null);
|
String itemName = site.optString("itemName", null);
|
||||||
double maxPoints = site.optDouble("points", -1);
|
double maxPoints = site.optDouble("points", -1);
|
||||||
|
|
||||||
gradebook.add(0, new Grade(itemName, grade, maxPoints));
|
gradebook.addGrade(new Grade(itemName, grade, maxPoints));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.e(new NetworkError(101505, 403, "Cannot parse gradebook!"));
|
log.e(new NetworkError(101505, 403, "Cannot parse gradebook!"));
|
||||||
log.e("ID:", i, "JSON:", sites);
|
log.e("ID:", i, "JSON:", sites);
|
||||||
@@ -73,14 +74,14 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
callback.onResponse(gradebook);
|
callback.onResponse(gradebook);
|
||||||
}, error -> {
|
}, error -> {
|
||||||
if (error.networkResponse.statusCode == 400)
|
if (error.networkResponse.statusCode == 400)
|
||||||
callback.onResponse(new ArrayList<>());
|
callback.onResponse(new Gradebook());
|
||||||
else
|
else
|
||||||
errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook!"));
|
errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook!"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void upgradeBB(String ID, NetworkCallback<ArrayList<Grade>> callback, NetworkErrorCallback errorCallback) {
|
protected void upgradeBB(String ID, NetworkCallback<Gradebook> callback, NetworkErrorCallback errorCallback) {
|
||||||
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null || !mLogin.getLoginTokenBB().isAvailable()) {
|
if (!mLogin.isInOnlineMode() || mLogin.getLoginTokenBB() == null || !mLogin.getLoginTokenBB().isAvailable()) {
|
||||||
errorCallback.onError(new NetworkError(101510, 500, "Currently running in offline mode!"));
|
errorCallback.onError(new NetworkError(101510, 500, "Currently running in offline mode!"));
|
||||||
return;
|
return;
|
||||||
@@ -117,7 +118,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<Grade> result = new ArrayList<>();
|
Gradebook result = new Gradebook();
|
||||||
for (int i = 0; i < grades.length(); i++) {
|
for (int i = 0; i < grades.length(); i++) {
|
||||||
for (int j = 0; j < gradeColumns.length(); j++) {
|
for (int j = 0; j < gradeColumns.length(); j++) {
|
||||||
try {
|
try {
|
||||||
@@ -133,7 +134,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
JSONObject score = column.optJSONObject("score");
|
JSONObject score = column.optJSONObject("score");
|
||||||
double maxPoints = score != null ? score.optDouble("possible", 0) : 0;
|
double maxPoints = score != null ? score.optDouble("possible", 0) : 0;
|
||||||
|
|
||||||
result.add(new Grade(name, points, maxPoints));
|
result.addGrade(new Grade(name, points, maxPoints));
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
log.e(new NetworkError(101515, 400, "Cannot parse grades!"));
|
log.e(new NetworkError(101515, 400, "Cannot parse grades!"));
|
||||||
log.e("ID:", i, "JSON-grades:", grades);
|
log.e("ID:", i, "JSON-grades:", grades);
|
||||||
@@ -147,7 +148,7 @@ public class ModulesGradebook extends PartModules<ArrayList<Grade>> {
|
|||||||
}, error -> errorCallback.onError(new NetworkError(101516, error.networkResponse.statusCode, "Cannot get gradebook columns!")));
|
}, error -> errorCallback.onError(new NetworkError(101516, error.networkResponse.statusCode, "Cannot get gradebook columns!")));
|
||||||
}, error -> {
|
}, error -> {
|
||||||
if (error.networkResponse.statusCode == 403)
|
if (error.networkResponse.statusCode == 403)
|
||||||
callback.onResponse(new ArrayList<>());
|
callback.onResponse(new Gradebook());
|
||||||
else
|
else
|
||||||
errorCallback.onError(new NetworkError(101517, error.networkResponse.statusCode, "Cannot get gradebook entries!"));
|
errorCallback.onError(new NetworkError(101517, error.networkResponse.statusCode, "Cannot get gradebook entries!"));
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import de.sebse.fuplanner.services.kvv.types.Assignment;
|
|||||||
import de.sebse.fuplanner.services.kvv.types.AssignmentList;
|
import de.sebse.fuplanner.services.kvv.types.AssignmentList;
|
||||||
import de.sebse.fuplanner.services.kvv.types.EventList;
|
import de.sebse.fuplanner.services.kvv.types.EventList;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Grade;
|
import de.sebse.fuplanner.services.kvv.types.Grade;
|
||||||
|
import de.sebse.fuplanner.services.kvv.types.Gradebook;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Modules;
|
import de.sebse.fuplanner.services.kvv.types.Modules;
|
||||||
import de.sebse.fuplanner.services.kvv.types.Resource;
|
import de.sebse.fuplanner.services.kvv.types.Resource;
|
||||||
import de.sebse.fuplanner.tools.CustomNotificationManager;
|
import de.sebse.fuplanner.tools.CustomNotificationManager;
|
||||||
@@ -126,7 +127,7 @@ public class KVVSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
final ArrayList<Announcement> announcements = module.announcements;
|
final ArrayList<Announcement> announcements = module.announcements;
|
||||||
final AssignmentList assignments = module.assignments;
|
final AssignmentList assignments = module.assignments;
|
||||||
final EventList events = module.events;
|
final EventList events = module.events;
|
||||||
final ArrayList<Grade> gradebook = module.gradebook;
|
final Gradebook gradebook = module.gradebook;
|
||||||
final ArrayList<Resource> resources = module.resources;
|
final ArrayList<Resource> resources = module.resources;
|
||||||
mKVV.modules().details().recv(module, success1 -> {
|
mKVV.modules().details().recv(module, success1 -> {
|
||||||
if (success1.second) {
|
if (success1.second) {
|
||||||
|
|||||||
@@ -0,0 +1,138 @@
|
|||||||
|
package de.sebse.fuplanner.services.kvv.types;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Gradebook implements Serializable, Iterable<Grade> {
|
||||||
|
private ArrayList<Grade> gradebook = new ArrayList<>();
|
||||||
|
private final static String[] EXAM_KEYWORDS = new String[] {"exam", "klausur", "prüfung"};
|
||||||
|
private final static String[] ASSIGNMENT_KEYWORDS = new String[] {"übung", "assignment", "blatt", "sheet", "exercise"};
|
||||||
|
|
||||||
|
public void addGrade(Grade grade) {
|
||||||
|
gradebook.add(0, grade);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategorizedGrades getAutoCategorizedGrades() {
|
||||||
|
ArrayList<Grade> exams = new ArrayList<>();
|
||||||
|
ArrayList<Grade> assignments = new ArrayList<>();
|
||||||
|
ArrayList<Grade> others = new ArrayList<>();
|
||||||
|
for (Grade grade : gradebook) {
|
||||||
|
boolean found = false;
|
||||||
|
String name = grade.getItemName().toLowerCase();
|
||||||
|
for (String keyword : EXAM_KEYWORDS) {
|
||||||
|
if (name.contains(keyword)) {
|
||||||
|
exams.add(grade);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) continue;
|
||||||
|
for (String keyword : ASSIGNMENT_KEYWORDS) {
|
||||||
|
if (name.contains(keyword)) {
|
||||||
|
assignments.add(grade);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) continue;
|
||||||
|
others.add(grade);
|
||||||
|
}
|
||||||
|
return new CategorizedGrades(exams, assignments, others);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradebookOutput getUncategorizedGrades() {
|
||||||
|
return new GradebookOutput(gradebook);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public Iterator<Grade> iterator() {
|
||||||
|
return gradebook.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CategorizedGrades {
|
||||||
|
private GradebookOutput exams;
|
||||||
|
private GradebookOutput assignments;
|
||||||
|
private GradebookOutput others;
|
||||||
|
|
||||||
|
private CategorizedGrades(List<Grade> exams, List<Grade> assignments, List<Grade> others) {
|
||||||
|
this.exams = new GradebookOutput(exams);
|
||||||
|
this.assignments = new GradebookOutput(assignments);
|
||||||
|
this.others = new GradebookOutput(others);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradebookOutput getExams() {
|
||||||
|
return exams;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradebookOutput getAssignments() {
|
||||||
|
return assignments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GradebookOutput getOthers() {
|
||||||
|
return others;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GradebookOutput {
|
||||||
|
public List<Grade> grades;
|
||||||
|
|
||||||
|
private GradebookOutput(List<Grade> grades) {
|
||||||
|
this.grades = Collections.unmodifiableList(grades);
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPercentage() {
|
||||||
|
float maxPoints = 0;
|
||||||
|
float userPoints = 0;
|
||||||
|
if (grades != null) {
|
||||||
|
for (Grade g : grades){
|
||||||
|
maxPoints += g.getMaxPoints();
|
||||||
|
userPoints += g.getPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (maxPoints == 0)
|
||||||
|
return 0;
|
||||||
|
return userPoints / maxPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getMaxPointSum() {
|
||||||
|
float maxPoints = 0;
|
||||||
|
if (grades != null) {
|
||||||
|
for (Grade g : grades){
|
||||||
|
maxPoints += g.getMaxPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getUserPointSum() {
|
||||||
|
float userPoints = 0;
|
||||||
|
if (grades != null) {
|
||||||
|
for (Grade g : grades){
|
||||||
|
userPoints += g.getPoints();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return userPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Grade getBestGrade() {
|
||||||
|
Grade bestGrade = null;
|
||||||
|
double bestValue = -1;
|
||||||
|
if (grades != null) {
|
||||||
|
for (Grade g : grades){
|
||||||
|
double perc = g.getPoints() / g.getMaxPoints();
|
||||||
|
if (perc > bestValue) {
|
||||||
|
bestValue = perc;
|
||||||
|
bestGrade = g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bestGrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -178,23 +178,9 @@ public class Modules implements Iterable<Modules.Module>, Serializable {
|
|||||||
@Nullable public ArrayList<Announcement> announcements;
|
@Nullable public ArrayList<Announcement> announcements;
|
||||||
@Nullable public AssignmentList assignments;
|
@Nullable public AssignmentList assignments;
|
||||||
@Nullable public EventList events;
|
@Nullable public EventList events;
|
||||||
@Nullable public ArrayList<Grade> gradebook;
|
@Nullable public Gradebook gradebook;
|
||||||
@Nullable public ArrayList<Resource> resources;
|
@Nullable public ArrayList<Resource> resources;
|
||||||
|
|
||||||
public float getGradebookPercent(){
|
|
||||||
float maxPoint = 0;
|
|
||||||
float userPoint = 0;
|
|
||||||
if (gradebook != null) {
|
|
||||||
for (Grade g : gradebook){
|
|
||||||
maxPoint += g.getMaxPoints();
|
|
||||||
userPoint += g.getPoints();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (maxPoint == 0)
|
|
||||||
return 0;
|
|
||||||
return userPoint/maxPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull LinkedHashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID, int moduleType) {
|
private Module(@Nullable Semester semester, @NotNull HashSet<String> lvNumber, @NotNull String title, @NotNull LinkedHashSet<Lecturer> lecturer, @Nullable String type, @Nullable String description, @NotNull String ID, int moduleType) {
|
||||||
|
|
||||||
title = title.replaceAll("(.*?) (S[0-9]{2}|W[0-9/]{5})", "$1");
|
title = title.replaceAll("(.*?) (S[0-9]{2}|W[0-9/]{5})", "$1");
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
xmlns:card_view="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_margin="@dimen/cardview_margin"
|
||||||
|
card_view:cardElevation="@dimen/cardview_elevation">
|
||||||
|
<RelativeLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
@@ -47,3 +53,4 @@
|
|||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
tools:text="10" />
|
tools:text="10" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
31
app/src/main/res/layout/list_moddetails_gradebook_title.xml
Normal file
31
app/src/main/res/layout/list_moddetails_gradebook_title.xml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout 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="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/title"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/cardview_margin"
|
||||||
|
android:layout_marginStart="@dimen/cardview_margin"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:layout_marginRight="@dimen/cardview_margin"
|
||||||
|
android:layout_marginEnd="@dimen/cardview_margin"
|
||||||
|
tools:text="Caption"
|
||||||
|
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/string"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginLeft="@dimen/cardview_margin"
|
||||||
|
android:layout_marginStart="@dimen/cardview_margin"
|
||||||
|
android:layout_marginBottom="4dp"
|
||||||
|
android:layout_marginRight="@dimen/cardview_margin"
|
||||||
|
android:layout_marginEnd="@dimen/cardview_margin"
|
||||||
|
tools:text="Caption"
|
||||||
|
style="@style/FUTheme.itemValue" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
<string name="no_items_available">Keine Einträge vorhanden!</string>
|
<string name="no_items_available">Keine Einträge vorhanden!</string>
|
||||||
<string name="events">Veranstaltungen</string>
|
<string name="events">Veranstaltungen</string>
|
||||||
<string name="gradebook">Noten</string>
|
<string name="gradebook">Noten</string>
|
||||||
<string name="current_percentage">Aktuelle Prozentzahl: %1$.2f \%%</string>
|
<string name="current_percentage">Punkte: %1$.1f / %2$.1f\nProzentsatz: %3$.1f \%%\nBeste Note: %4$.1f / %5$.1f - %6$.1f \%% (%7$s)</string>
|
||||||
<string name="offline_mode">Offline-Modus</string>
|
<string name="offline_mode">Offline-Modus</string>
|
||||||
<string name="refresh_failed">Aktualisieren fehlgeschlagen…</string>
|
<string name="refresh_failed">Aktualisieren fehlgeschlagen…</string>
|
||||||
<string name="share_intent">Hey, schau\' dir die neue KVV App an: %1$s</string>
|
<string name="share_intent">Hey, schau\' dir die neue KVV App an: %1$s</string>
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
<string name="no_items_available">No items available!</string>
|
<string name="no_items_available">No items available!</string>
|
||||||
<string name="events">Events</string>
|
<string name="events">Events</string>
|
||||||
<string name="gradebook">Gradebook</string>
|
<string name="gradebook">Gradebook</string>
|
||||||
<string name="current_percentage">Current Percentage: %1$.2f \%%</string>
|
<string name="current_percentage">Points: %1$.1f / %2$.1f\nPercentage: %3$.1f \%%\nBest Grade: %4$.1f / %5$.1f - %6$.1f \%% (%7$s)</string>
|
||||||
<string name="offline_mode">Offline Mode</string>
|
<string name="offline_mode">Offline Mode</string>
|
||||||
<string name="refresh_failed">Refresh failed…</string>
|
<string name="refresh_failed">Refresh failed…</string>
|
||||||
<string name="share_intent">Hey, check out the new KVV app: %1$s</string>
|
<string name="share_intent">Hey, check out the new KVV app: %1$s</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user