Commit 3db31167 authored by Lennart Bader's avatar Lennart Bader
Browse files

New Beta version.

Fixes:
- VPlan Tab Titles
- Cache clear on logout
Changes + New Features
- Day Name displayed in calendar
- VRR updated: Delay + type added + auto refresh
- VPlan Layout changed
- VPlan animation changed
parent 2a17c0b8
Pipeline #21 failed with stage
in 3 minutes and 20 seconds
No preview for this file type
......@@ -7,8 +7,8 @@ android {
applicationId "de.mytfg.apps.mytfg"
minSdkVersion 15
targetSdkVersion 25
versionCode 7
versionName "0.5.2b"
versionCode 8
versionName "0.5.3b"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
......@@ -26,11 +26,12 @@ dependencies {
})
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support:support-v4:25.2.0'
compile 'com.android.support:design:25.2.0'
compile 'com.android.support:cardview-v7:25.2.0'
compile 'com.android.support:appcompat-v7:25.3.0'
compile 'com.android.support:support-v4:25.3.0'
compile 'com.android.support:design:25.3.0'
compile 'com.android.support:cardview-v7:25.3.0'
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile 'ch.acra:acra:4.7.0'
compile 'com.google.firebase:firebase-messaging:10.2.0'
compile 'com.github.AndroidDeveloperLB:AutoFitTextView:4'
}
......@@ -14,6 +14,7 @@ public class EventsEntryHolder extends RecyclerView.ViewHolder {
private TextView title;
private TextView date;
private TextView day;
private TextView dayname;
private TextView month;
private TextView year;
private TextView location;
......@@ -28,6 +29,7 @@ public class EventsEntryHolder extends RecyclerView.ViewHolder {
title = (TextView) view.findViewById(R.id.event_title);
//date = (TextView) view.findViewById(R.id.event_date);
day = (TextView) view.findViewById(R.id.event_day);
dayname = (TextView) view.findViewById(R.id.event_dayname);
month = (TextView) view.findViewById(R.id.event_month);
year = (TextView) view.findViewById(R.id.event_year);
......@@ -41,6 +43,7 @@ public class EventsEntryHolder extends RecyclerView.ViewHolder {
day.setText(MyTFGApi.getDay(ts));
month.setText(MyTFGApi.getMonth(ts));
year.setText(MyTFGApi.getYear(ts));
dayname.setText(MyTFGApi.getDayname(ts));
String time = entry.getTime();
String loc = entry.getLocation();
if (time.length() > 0) {
......
......@@ -4,8 +4,11 @@ import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import com.lb.auto_fit_textview.AutoResizeTextView;
import de.mytfg.apps.mytfg.R;
import de.mytfg.apps.mytfg.objects.VplanEntry;
import de.mytfg.apps.mytfg.tools.Settings;
......@@ -20,6 +23,8 @@ public class PlanEntryHolder extends RecyclerView.ViewHolder {
private TextView substHeader;
private TextView comment;
private TextView commentHeader;
private AutoResizeTextView summary;
private ImageView arrow;
private Context context;
private CardView cardView;
......@@ -30,11 +35,11 @@ public class PlanEntryHolder extends RecyclerView.ViewHolder {
cardView = (CardView) view;
lesson = (TextView) view.findViewById(R.id.plan_entry_lesson);
cls = (TextView) view.findViewById(R.id.plan_entry_class);
summary = (AutoResizeTextView) view.findViewById(R.id.plan_entry_summary);
plan = (TextView) view.findViewById(R.id.plan);
subst = (TextView) view.findViewById(R.id.subst);
comment = (TextView) view.findViewById(R.id.comment);
substHeader = (TextView) view.findViewById(R.id.subst_header);
commentHeader = (TextView) view.findViewById(R.id.comment_header);
arrow = (ImageView) view.findViewById(R.id.arrow);
}
public void update(VplanEntry planEntry) {
......@@ -46,27 +51,35 @@ public class PlanEntryHolder extends RecyclerView.ViewHolder {
String substText = settings.getBool("plan_fulltext") ? planEntry.getSubstText() : planEntry.getSubstitution();
plan.setText(planText);
if (planEntry.getSubstitution().isEmpty()) {
substHeader.setVisibility(GONE);
//substHeader.setVisibility(GONE);
subst.setVisibility(GONE);
} else {
subst.setText(substText);
subst.setVisibility(View.VISIBLE);
substHeader.setVisibility(View.VISIBLE);
//substHeader.setVisibility(View.VISIBLE);
}
if (planEntry.getComment().isEmpty()) {
comment.setVisibility(GONE);
commentHeader.setVisibility(GONE);
//commentHeader.setVisibility(GONE);
} else {
comment.setText(planEntry.getComment());
commentHeader.setVisibility(View.VISIBLE);
//commentHeader.setVisibility(View.VISIBLE);
comment.setVisibility(View.VISIBLE);
}
if (planEntry.getComment().isEmpty() && planEntry.getSubstitution().isEmpty()) {
arrow.setVisibility(GONE);
} else {
arrow.setVisibility(View.VISIBLE);
}
cls.setText(planEntry.getCls());
if (planEntry.isOwn()) {
cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorPrimaryLight));
} else {
cardView.setCardBackgroundColor(context.getResources().getColor(R.color.colorSecondaryLight));
}
summary.setText(planEntry.getSummary());
}
public void setOnClickListener(CardView.OnClickListener listener) {
......
......@@ -75,7 +75,7 @@ public class RecylcerPlanAdapter extends RecyclerView.Adapter<PlanEntryHolder> {
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
Animation animation = AnimationUtils.loadAnimation(context, R.anim.slide_in_bottom);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
......
......@@ -4,6 +4,7 @@ import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import de.mytfg.apps.mytfg.R;
......@@ -13,6 +14,10 @@ public class VrrEntryHolder extends RecyclerView.ViewHolder {
private TextView line;
private TextView direction;
private TextView arrival;
private TextView type;
private TextView delay;
private ImageView typeImg;
private Context context;
private CardView cardView;
......@@ -24,12 +29,27 @@ public class VrrEntryHolder extends RecyclerView.ViewHolder {
line = (TextView) view.findViewById(R.id.vrr_entry_line);
direction = (TextView) view.findViewById(R.id.vrr_dir);
arrival = (TextView) view.findViewById(R.id.vrr_time);
type = (TextView) view.findViewById(R.id.vrr_type);
typeImg = (ImageView) view.findViewById(R.id.vrr_type_img);
delay = (TextView) view.findViewById(R.id.vrr_delay);
}
public void update(VrrEntry entry) {
line.setText(entry.getLine());
direction.setText(entry.getDirection());
arrival.setText(entry.getArrival());
if ("U-Bahn".equals(entry.getType())) {
typeImg.setImageResource(R.drawable.ic_vrr_tram);
} else {
typeImg.setImageResource(R.drawable.ic_vrr_bus);
}
type.setText(entry.getType());
if (entry.getDelay() > 0) {
delay.setVisibility(View.VISIBLE);
delay.setText(entry.getDelayText());
} else {
delay.setVisibility(View.GONE);
}
}
public void setOnClickListener(CardView.OnClickListener listener) {
......
......@@ -198,8 +198,8 @@ public class MyTFGApi {
.remove("username")
.apply();
}
Vplan.clearCache("heute", context);
Vplan.clearCache("morgen", context);
Vplan.clearCache("today", context);
Vplan.clearCache("tomorrow", context);
}
/**
......@@ -387,6 +387,18 @@ public class MyTFGApi {
}
}
public static String getDayname(long timestamp) {
timestamp = timestamp * 1000;
try{
DateFormat sdf = new SimpleDateFormat("EEE", Locale.GERMAN);
Date netDate = (new Date(timestamp));
return sdf.format(netDate);
}
catch(Exception ex){
return "--";
}
}
public static String getYear(long timestamp) {
timestamp = timestamp * 1000;
try{
......
package de.mytfg.apps.mytfg.fragments;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
......@@ -166,7 +167,7 @@ public class PlanFragment extends AuthenticationFragment {
if (message == null) {
message = msg;
} else {
message += "\n" + msg;
message += "\n\n" + msg;
}
}
if (message == null) {
......@@ -225,9 +226,28 @@ public class PlanFragment extends AuthenticationFragment {
tabLayout.setupWithViewPager(viewPager);
}
Runnable runnable = new Runnable() {
@Override
public void run() {
setupViewpager();
}
};
Handler handler = new Handler();
handler.postDelayed(runnable, 10);
this.showcase();
}
private void setupViewpager() {
ViewPager viewPager = (ViewPager) view.findViewById(R.id.plan_pager);
TabLayout tabLayout = context.getToolbarManager().getTabs();
if (tabLayout != null) {
tabLayout.setupWithViewPager(viewPager);
}
}
private void showcase() {
ShowCaseManager scm = new ShowCaseManager(getContext());
......
......@@ -104,6 +104,8 @@ public class SettingsFragment extends AuthenticationFragment {
public void onClick(View view) {
MyTFGApi api = new MyTFGApi(context);
api.logout(false);
api.clearAdditionalClasses();
CoordinatorLayout coordinatorLayout = (CoordinatorLayout) context.findViewById(R.id.coordinator_layout);
Snackbar snackbar = Snackbar
......
package de.mytfg.apps.mytfg.fragments;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.GridLayoutManager;
......@@ -8,9 +9,14 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
import de.mytfg.apps.mytfg.R;
import de.mytfg.apps.mytfg.activities.MainActivity;
import de.mytfg.apps.mytfg.adapters.RecylcerVrrAdapter;
......@@ -18,12 +24,20 @@ import de.mytfg.apps.mytfg.api.SuccessCallback;
import de.mytfg.apps.mytfg.objects.Vrr;
import de.mytfg.apps.mytfg.objects.VrrEntry;
import de.mytfg.apps.mytfg.tools.ItemOffsetDecoration;
import de.mytfg.apps.mytfg.tools.Settings;
public class VrrFragment extends AuthenticationFragment {
private View view;
private RecylcerVrrAdapter adapter;
private RecyclerView recyclerView;
private SwipeRefreshLayout swipeRefreshLayout;
private boolean autoRefresh;
private MainActivity context;
private Handler handler;
private Runnable updateRunner;
private boolean timerActive;
private static final int updateInterval = 10000;
public VrrFragment() {
}
......@@ -33,7 +47,7 @@ public class VrrFragment extends AuthenticationFragment {
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_vrr, container, false);
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.base_refreshLayout);
MainActivity context = (MainActivity)this.getActivity();
context = (MainActivity)this.getActivity();
recyclerView = (RecyclerView) view.findViewById(R.id.vrr_recylcerview);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), 1);
......@@ -41,6 +55,9 @@ public class VrrFragment extends AuthenticationFragment {
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.addItemDecoration(new ItemOffsetDecoration(getContext(), R.dimen.cardview_spacing));
Settings settings = new Settings(context);
autoRefresh = settings.getBool("vrr_auto_refresh");
setHasOptionsMenu(true);
context.getToolbarManager()
.clear()
......@@ -55,6 +72,21 @@ public class VrrFragment extends AuthenticationFragment {
}
});
handler = new Handler();
updateRunner = new Runnable() {
@Override
public void run() {
try {
displayVrr();
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
handler.postDelayed(updateRunner, updateInterval);
}
}
};
this.displayVrr();
......@@ -64,12 +96,66 @@ public class VrrFragment extends AuthenticationFragment {
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
inflater.inflate(R.menu.vrr_menu, menu);
menu.getItem(0).setChecked(autoRefresh);
if (autoRefresh) {
menu.getItem(0).setIcon(R.drawable.ic_action_vrr_enabled_autorefresh);
startTimer();
} else {
menu.getItem(0).setIcon(R.drawable.ic_action_vrr_disabled_autorefresh);
}
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.vrr_auto_refresh:
item.setChecked(!item.isChecked());
autoRefresh = item.isChecked();
Settings settings = new Settings(context);
settings.save("vrr_auto_refresh", autoRefresh);
if (autoRefresh) {
context.getNavi().snackbar(context.getString(R.string.vrr_autorefresh_enabled));
item.setIcon(R.drawable.ic_action_vrr_enabled_autorefresh);
startTimer();
} else {
context.getNavi().snackbar(context.getString(R.string.vrr_autorefresh_disabled));
item.setIcon(R.drawable.ic_action_vrr_disabled_autorefresh);
stopTimer();
}
return true;
}
return super.onOptionsItemSelected(item);
}
private void startTimer() {
if (!timerActive) {
updateRunner.run();
timerActive = true;
}
}
private void stopTimer() {
timerActive = false;
handler.removeCallbacks(updateRunner);
}
@Override
public void onResume() {
super.onResume();
if (autoRefresh) {
startTimer();
}
}
@Override
public void onPause() {
if (autoRefresh) {
stopTimer();
}
super.onPause();
}
public void displayVrr() {
......@@ -82,8 +168,11 @@ public class VrrFragment extends AuthenticationFragment {
public void callback(boolean success) {
swipeRefreshLayout.setRefreshing(false);
if (success) {
adapter = new RecylcerVrrAdapter(getContext());
recyclerView.setAdapter(adapter);
if (adapter == null) {
adapter = new RecylcerVrrAdapter(getContext());
recyclerView.setAdapter(adapter);
}
adapter.clear();
for (VrrEntry entry : vrr.getEntries()) {
adapter.addItem(entry);
}
......
......@@ -2,6 +2,7 @@ package de.mytfg.apps.mytfg.objects;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import org.json.JSONArray;
......@@ -215,6 +216,6 @@ public class Vplan extends MytfgObject {
}
public static void clearCache(String day, Context context) {
JsonFileManager.clear("vplan_" + day, context);
Log.d("CLEAR CACHE", "" + JsonFileManager.clear("vplan_" + day, context));
}
}
......@@ -18,6 +18,7 @@ public class VplanEntry extends MytfgObject {
private String subst_text;
private String comment;
private String teacher;
private String summary;
private boolean own;
......@@ -56,6 +57,7 @@ public class VplanEntry extends MytfgObject {
teacher = data.getString("teacher");
subst_text = data.getString("subst_text");
plan_text = data.getString("plan_text");
summary = data.getString("shortage");
} catch (JSONException ex) {
// TODO: Remove this line:
ex.printStackTrace();
......@@ -96,6 +98,10 @@ public class VplanEntry extends MytfgObject {
return subst_text;
}
public String getSummary() {
return summary;
}
/**
* Checks wheter this entry contains information matching the given filter.
* @param filter The filter to apply
......@@ -108,6 +114,7 @@ public class VplanEntry extends MytfgObject {
|| getPlan().toLowerCase().contains(filter)
|| getPlanText().toLowerCase().contains(filter)
|| getSubstText().toLowerCase().contains(filter)
|| getSummary().toLowerCase().contains(filter)
|| getSubstitution().toLowerCase().contains(filter);
}
......
......@@ -54,11 +54,13 @@ public class Vrr extends MytfgObject {
this.entries = new LinkedList<>();
try {
JSONObject vrr = result.getJSONObject("vrr");
JSONArray entries = vrr.getJSONArray("preformatted");
JSONArray entries = vrr.getJSONArray("relevant");
for (int i = 0; i < entries.length(); ++i) {
VrrEntry entry = new VrrEntry();
entry.load(entries.getJSONArray(i));
this.entries.add(entry);
entry.load(entries.getJSONObject(i));
if (!entry.getDirection().isEmpty()) {
this.entries.add(entry);
}
}
} catch (JSONException ex) {
ex.printStackTrace();
......
......@@ -2,6 +2,9 @@ package de.mytfg.apps.mytfg.objects;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import de.mytfg.apps.mytfg.api.SuccessCallback;
......@@ -13,6 +16,12 @@ public class VrrEntry extends MytfgObject {
private String line;
private String direction;
private String arrival;
private String type;
private int delay;
private ArrayList<String> route;
private String platform;
private String sched;
private String date;
/**
* Do not use this method. Use the load method and pass a JSON Object.
* @param callback Always called with false
......@@ -22,14 +31,22 @@ public class VrrEntry extends MytfgObject {
callback.callback(false);
}
public boolean load(JSONArray data) {
public boolean load(JSONObject data) {
if (data == null) {
return false;
}
try {
line = data.getString(0);
direction = data.getString(1);
arrival = data.getString(2);
line = data.getString("line");
direction = data.getString("destination");
arrival = data.getString("arrival");
delay = data.getInt("delay");
type = data.getString("type");
route = new ArrayList<>();
for (int i = 0; i < data.getJSONArray("route").length(); ++i) {
route.add(data.getJSONArray("route").getString(i));
}
sched = data.getString("sched");
date = data.getString("real");
} catch (JSONException ex) {
return false;
}
......@@ -47,4 +64,32 @@ public class VrrEntry extends MytfgObject {
public String getArrival() {
return arrival;
}
public String getType() {
return type;
}
public int getDelay() {
return delay;
}
public ArrayList<String> getRoute() {
return route;
}
public String getPlatform() {
return platform;
}
public String getSched() {
return sched;
}
public String getDate() {
return date;
}
public String getDelayText() {
return "(+ " + getDelay() + " Min)";
}
}
......@@ -50,6 +50,7 @@ public class JsonFileManager {
}
public static boolean clear(String filename, Context context) {
Log.d("Delete File", filename);