diff --git a/.idea/misc.xml b/.idea/misc.xml
index 4e024a8..a8cce1b 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -25,5 +25,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
index bee9e70..62306f1 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -2,7 +2,7 @@
-
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 8306744..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -2,6 +2,5 @@
-
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 87c4fca..cab2e11 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -34,7 +34,7 @@ dependencies {
})
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:design:27.1.1'
- implementation 'com.android.support.constraint:constraint-layout:1.1.1'
+ implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.android.volley:volley:1.0.0'
//noinspection GradleDependency
implementation 'com.google.android.gms:play-services-auth:15.0.0'
@@ -47,5 +47,7 @@ dependencies {
implementation 'org.jetbrains:annotations-java5:15.0'
implementation 'com.github.quivr:android-week-view:2.0.2'//com.github.alamkanak:android-week-view:1.2.6
implementation 'com.ms-square:expandableTextView:0.1.4'
+ // https://github.com/bignerdranch/expandable-recycler-view
+ implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
implementation files('libs/jericho-html-3.4.jar')
}
diff --git a/app/src/main/java/de/sebse/fuplanner/MainActivity.java b/app/src/main/java/de/sebse/fuplanner/MainActivity.java
index 36df966..904ac8a 100644
--- a/app/src/main/java/de/sebse/fuplanner/MainActivity.java
+++ b/app/src/main/java/de/sebse/fuplanner/MainActivity.java
@@ -75,16 +75,16 @@ public class MainActivity extends AppCompatActivity
getGoogleAuth().getLoginState(credentials -> {
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
MainActivity.this.getKVV().endUpdate();
- changeLoginState(null);
+ toLogoutState();
return;
}
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
MainActivity.this.getKVV().endUpdate();
- changeLoginState(credentials);
+ toLoginState(credentials);
}, error -> {
log.e(error);
MainActivity.this.getKVV().endUpdate();
- changeLoginState(null);
+ toLogoutState();
});
});
});
@@ -149,7 +149,7 @@ public class MainActivity extends AppCompatActivity
if (credentials != null) {
MainActivity.this.getGoogleAuth().deleteLoginState(credentials.getUsername(), credentials.getPassword());
}
- MainActivity.this.changeLoginState(null);
+ MainActivity.this.toLogoutState();
});
break;
}
@@ -187,56 +187,60 @@ public class MainActivity extends AppCompatActivity
return this.mKVV;
}
- private void changeLoginState(Credentials credentials) {
- log.d("change login state");
+ private void toLoginState(Credentials credentials) {
if (credentials == null) {
- log.d("null");
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.replace(R.id.fragcontainer, LoginFragment.newInstance());
- fragmentTransaction.commit();
- findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
-
- NavigationView navigationView = findViewById(R.id.nav_view);
- View header = navigationView.getHeaderView(0);
- header.findViewById(R.id.imageView).setVisibility(View.GONE);
- header.findViewById(R.id.login_name).setVisibility(View.GONE);
- header.findViewById(R.id.login_page).setVisibility(View.VISIBLE);
- navigationView.getMenu().clear();
- navigationView.inflateMenu(R.menu.activity_main_drawer);
-
+ toLogoutState();
} else {
- log.d(credentials.getUsername());
- FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
- fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
- fragmentTransaction.commit();
- findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
-
- final NavigationView navigationView = findViewById(R.id.nav_view);
- View header = navigationView.getHeaderView(0);
- header.findViewById(R.id.imageView).setVisibility(View.VISIBLE);
- header.findViewById(R.id.login_name).setVisibility(View.VISIBLE);
- header.findViewById(R.id.login_page).setVisibility(View.GONE);
- navigationView.getMenu().clear();
- navigationView.inflateMenu(R.menu.activity_main_drawer_login);
- navigationView.setCheckedItem(R.id.nav_modules);
- getKVV().getModuleList(success -> {
- log.d("Modules.get", success.size());
- //SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
- int i = 0;
- for (Iterator it = success.latestSemesterIterator(); it.hasNext(); ) {
- Modules.Module module = it.next();
- MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
- final int finalI = i;
- menuItem.setOnMenuItemClickListener(item -> {
- onModulesFragmentInteraction(finalI);
- return false;
- });
- i++;
- }
- }, error -> log.d("Modules.error", error));
+ toLoginState(credentials.getUsername());
}
}
+ private void toLogoutState() {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ fragmentTransaction.replace(R.id.fragcontainer, LoginFragment.newInstance());
+ fragmentTransaction.commit();
+ findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
+
+ NavigationView navigationView = findViewById(R.id.nav_view);
+ View header = navigationView.getHeaderView(0);
+ header.findViewById(R.id.imageView).setVisibility(View.GONE);
+ header.findViewById(R.id.login_name).setVisibility(View.GONE);
+ header.findViewById(R.id.login_page).setVisibility(View.VISIBLE);
+ navigationView.getMenu().clear();
+ navigationView.inflateMenu(R.menu.activity_main_drawer);
+ }
+
+ private void toLoginState(String username) {
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+ fragmentTransaction.replace(R.id.fragcontainer, ModulesFragment.newInstance());
+ fragmentTransaction.commit();
+ findViewById(R.id.app_bar_layout).setVisibility(View.VISIBLE);
+
+ final NavigationView navigationView = findViewById(R.id.nav_view);
+ View header = navigationView.getHeaderView(0);
+ header.findViewById(R.id.imageView).setVisibility(View.VISIBLE);
+ header.findViewById(R.id.login_name).setVisibility(View.VISIBLE);
+ header.findViewById(R.id.login_page).setVisibility(View.GONE);
+ navigationView.getMenu().clear();
+ navigationView.inflateMenu(R.menu.activity_main_drawer_login);
+ navigationView.setCheckedItem(R.id.nav_modules);
+ getKVV().getModuleList(success -> {
+ log.d("Modules.get", success.size());
+ //SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
+ int i = 0;
+ for (Iterator it = success.latestSemesterIterator(); it.hasNext(); ) {
+ Modules.Module module = it.next();
+ MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
+ final int finalI = i;
+ menuItem.setOnMenuItemClickListener(item -> {
+ onModulesFragmentInteraction(finalI);
+ return false;
+ });
+ i++;
+ }
+ }, error -> log.e("Modules.error", error));
+ }
+
@@ -248,8 +252,8 @@ public class MainActivity extends AppCompatActivity
@Override
- public void onLoginFragmentInteraction(Credentials credentials) {
- changeLoginState(credentials);
+ public void onLoginFragmentInteraction(String username) {
+ toLoginState(username);
}
@Override
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/LoginFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/LoginFragment.java
index 3a4d1ad..323e76b 100644
--- a/app/src/main/java/de/sebse/fuplanner/fragments/LoginFragment.java
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/LoginFragment.java
@@ -8,13 +8,17 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.Button;
import android.widget.EditText;
+import java.io.IOException;
+
import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.R;
import de.sebse.fuplanner.services.GoogleAuth.Credentials;
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
import de.sebse.fuplanner.services.KVV.KVV;
+import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
/**
@@ -26,11 +30,6 @@ import de.sebse.fuplanner.tools.logging.Logger;
* create an instance of this fragment.
*/
public class LoginFragment extends Fragment {
- // TODO: Rename parameter arguments, choose names that match
- // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
-
- // TODO: Rename and change types of parameters
-
private OnLoginFragmentInteractionListener mListener;
private Logger log = new Logger(this);
@@ -44,7 +43,6 @@ public class LoginFragment extends Fragment {
*
* @return A new instance of fragment LoginFragment.
*/
- // TODO: Rename and change types and number of parameters
public static LoginFragment newInstance() {
LoginFragment fragment = new LoginFragment();
Bundle args = new Bundle();
@@ -61,47 +59,57 @@ public class LoginFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
-
View v = inflater.inflate(R.layout.fragment_login, container, false);
- View btn_login = v.findViewById(R.id.btn_login);
- if (btn_login != null) {
- btn_login.setOnClickListener(view -> {
- final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
- R.style.FUTheme_Dialog);
- progressDialog.setIndeterminate(true);
- progressDialog.setMessage("Authenticating...");
- progressDialog.show();
-
-
- EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
- EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
- if (input_usr != null) {
- if (input_pwd != null) {
- if (LoginFragment.this.getActivity() == null) {
- log.e("Login fragment has no activity!");
- return;
- }
- final String username = input_usr.getText().toString();
- final String password = input_pwd.getText().toString();
- final KVV kvv = ((MainActivity) LoginFragment.this.getActivity()).getKVV();
- final GoogleAuth gauth = ((MainActivity) LoginFragment.this.getActivity()).getGoogleAuth();
- kvv.login(username, password, success -> {
- progressDialog.dismiss();
- log.d("success", success.toString());
- gauth.setLoginState(username, password);
- if (LoginFragment.this.mListener != null) {
- Credentials cred = new Credentials(username, password);
- LoginFragment.this.mListener.onLoginFragmentInteraction(cred);
- }
- }, error -> {
- progressDialog.dismiss();
- log.e("error", error);
- });
- }
+ try {
+ Context context = getContext();
+ if (context != null) {
+ Modules modules = Modules.load(context);
+ if (modules != null) {
+ Button offline_btn = v.findViewById(R.id.btn_offline);
+ offline_btn.setVisibility(View.VISIBLE);
+ offline_btn.setText(v.getResources().getString(R.string.enter_offline_mode, modules.getUsername()));
+ offline_btn.setOnClickListener(v1 -> mListener.onLoginFragmentInteraction(modules.getUsername()));
}
- });
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
}
+ View btn_login = v.findViewById(R.id.btn_login);
+ btn_login.setOnClickListener(view -> {
+ final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
+ R.style.FUTheme_Dialog);
+ progressDialog.setIndeterminate(true);
+ progressDialog.setMessage("Authenticating...");
+ progressDialog.show();
+
+ EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
+ EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
+ if (input_usr != null) {
+ if (input_pwd != null) {
+ if (LoginFragment.this.getActivity() == null) {
+ log.e("Login fragment has no activity!");
+ return;
+ }
+ String username = input_usr.getText().toString();
+ String password = input_pwd.getText().toString();
+ KVV kvv = ((MainActivity) getActivity()).getKVV();
+ GoogleAuth gauth = ((MainActivity) getActivity()).getGoogleAuth();
+ kvv.login(username, password, success -> {
+ progressDialog.dismiss();
+ gauth.setLoginState(username, password);
+ if (mListener != null)
+ mListener.onLoginFragmentInteraction(username);
+ }, error -> {
+ progressDialog.dismiss();
+ log.e("Error on KVV login!", error);
+ });
+ }
+ }
+ });
+
return v;
}
@@ -135,7 +143,6 @@ public class LoginFragment extends Fragment {
* >Communicating with Other Fragments for more information.
*/
public interface OnLoginFragmentInteractionListener {
- // TODO: Update argument type and name
- void onLoginFragmentInteraction(Credentials credentials);
+ void onLoginFragmentInteraction(String username);
}
}
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java
index c4c23d6..8deaf4a 100644
--- a/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/ModulesFragment.java
@@ -45,7 +45,6 @@ public class ModulesFragment extends Fragment {
public static ModulesFragment newInstance() {
ModulesFragment fragment = new ModulesFragment();
Bundle args = new Bundle();
- /*args.putInt(ARG_COLUMN_COUNT, columnCount);*/
fragment.setArguments(args);
return fragment;
}
@@ -53,10 +52,6 @@ public class ModulesFragment extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- /*if (getArguments() != null) {
- mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
- }*/
}
@Override
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAdapter.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAdapter.java
index 79de3fa..7922e64 100644
--- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAdapter.java
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAdapter.java
@@ -17,25 +17,25 @@ class ModDetailAdapter extends FragmentStatePagerAdapter {
super(fm);
this.mContext = context;
this.mItemPos = itemPosition;
- log.d("constructor");
}
// Returns total number of pages
@Override
public int getCount() {
- return 2;
+ return 3;
}
// Returns the fragment to display for that page
@Override
public Fragment getItem(int position) {
- log.d("getItem");
switch (position) {
- case 0: // Fragment # 0 - This will show FirstFragment
+ case 0:
return ModDetailOverviewFragment.newInstance(mItemPos);
- case 1: // Fragment # 0 - This will show FirstFragment different title
+ case 1:
return ModDetailAnnounceFragment.newInstance(mItemPos);
+ case 2:
+ return ModDetailAssignmentFragment.newInstance(mItemPos);
default:
return null;
}
@@ -49,6 +49,8 @@ class ModDetailAdapter extends FragmentStatePagerAdapter {
return this.mContext.getResources().getString(R.string.overview);
case 1:
return this.mContext.getResources().getString(R.string.announcements);
+ case 2:
+ return this.mContext.getResources().getString(R.string.assignments);
default:
return "";
}
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceAdapter.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceAdapter.java
new file mode 100644
index 0000000..25a6bcb
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceAdapter.java
@@ -0,0 +1,108 @@
+package de.sebse.fuplanner.fragments.moddetails;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.TextView;
+
+import de.sebse.fuplanner.R;
+import de.sebse.fuplanner.services.KVV.types.Announcement;
+import de.sebse.fuplanner.services.KVV.types.Modules;
+import de.sebse.fuplanner.tools.Conversion;
+import de.sebse.fuplanner.tools.ui.ItemViewHolder;
+import de.sebse.fuplanner.tools.ui.StringViewHolder;
+
+public class ModDetailAnnounceAdapter extends BaseExpandableListAdapter {
+
+ private Modules.Module mModule = null;
+
+ @Override
+ public String getChild(int groupPosition, int childPosititon) {
+ return this.getGroup(groupPosition).getBody();
+ }
+
+ @Override
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ @Override
+ public View getChildView(int groupPosition, final int childPosition,
+ boolean isLastChild, View convertView, ViewGroup parent) {
+
+ final String childText = getChild(groupPosition, childPosition);
+
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.list_all_string, parent, false);
+ }
+
+ StringViewHolder itemHolder = new StringViewHolder(convertView);
+ itemHolder.mString.setText(childText);
+
+ return convertView;
+ }
+
+ @Override
+ public int getChildrenCount(int groupPosition) {
+ return 1;
+ }
+
+ @Override
+ public Announcement getGroup(int groupPosition) {
+ if (this.mModule != null && this.mModule.announcements != null)
+ return this.mModule.announcements.get(groupPosition);
+ else
+ return null;
+ }
+
+ @Override
+ public int getGroupCount() {
+ if (this.mModule != null && this.mModule.announcements != null)
+ return this.mModule.announcements.size();
+ else
+ return 0;
+ }
+
+ @Override
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ @Override
+ public View getGroupView(int groupPosition, boolean isExpanded,
+ View convertView, ViewGroup parent) {
+ Announcement announce = getGroup(groupPosition);
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.list_all_items, parent, false);
+ }
+
+ ItemViewHolder itemHolder = new ItemViewHolder(convertView);
+ itemHolder.mTitle.setText(announce.getTitle());
+ itemHolder.mSubLeft.setText(announce.getCreatedBy());
+ itemHolder.mSubRight.setText(Conversion.getModifiedDateTime(announce.getCreatedOn()));
+
+ return convertView;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return false;
+ }
+
+ public void setModule(Modules.Module module) {
+ this.mModule = module;
+ this.setModule();
+ }
+
+ public void setModule() {
+ this.notifyDataSetChanged();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java
index f0f0b6d..e08deb8 100644
--- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAnnounceFragment.java
@@ -1,14 +1,22 @@
package de.sebse.fuplanner.fragments.moddetails;
+import android.content.Context;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.widget.ExpandableListView;
+import de.sebse.fuplanner.MainActivity;
import de.sebse.fuplanner.R;
+import de.sebse.fuplanner.services.KVV.KVV;
+import de.sebse.fuplanner.services.KVV.types.Modules;
import de.sebse.fuplanner.tools.logging.Logger;
/**
@@ -24,6 +32,8 @@ public class ModDetailAnnounceFragment extends Fragment {
// TODO: Rename and change types of parameters
private int mItemPos;
private Logger log = new Logger(this);
+ private ModDetailAnnounceAdapter adapter;
+ private SwipeRefreshLayout swipeLayout;
public ModDetailAnnounceFragment() {
@@ -58,7 +68,41 @@ public class ModDetailAnnounceFragment extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
- return inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
+ View view = inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
+ // Set the adapter
+ Context context = view.getContext();
+ ExpandableListView expandableListView = view.findViewById(R.id.list);
+ //expandableListView.setLayoutManager(new LinearLayoutManager(context));
+ adapter = new ModDetailAnnounceAdapter();
+ expandableListView.setAdapter(adapter);
+
+ // Getting SwipeContainerLayout
+ swipeLayout = view.findViewById(R.id.swipe_container);
+ // Adding Listener
+ swipeLayout.setOnRefreshListener(() -> refresh(true));
+ refresh(false);
+
+ return view;
+ }
+
+ private void refresh(boolean forceRefresh) {
+ if (getActivity() != null) {
+ KVV kvv = ((MainActivity) getActivity()).getKVV();
+ kvv.getModuleList((Modules success) -> {
+ Modules.Module module = success.get(mItemPos);
+ adapter.setModule(module);
+ kvv.getModuleAnnouncements(module, success1 -> {
+ adapter.setModule();
+ swipeLayout.setRefreshing(false);
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ });
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ }, forceRefresh);
+ }
}
}
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentAdapter.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentAdapter.java
new file mode 100644
index 0000000..9ecc73e
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentAdapter.java
@@ -0,0 +1,117 @@
+package de.sebse.fuplanner.fragments.moddetails;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseExpandableListAdapter;
+
+import de.sebse.fuplanner.R;
+import de.sebse.fuplanner.services.KVV.types.Announcement;
+import de.sebse.fuplanner.services.KVV.types.Assignment;
+import de.sebse.fuplanner.services.KVV.types.Modules;
+import de.sebse.fuplanner.tools.Conversion;
+import de.sebse.fuplanner.tools.ui.ItemViewHolder;
+import de.sebse.fuplanner.tools.ui.StringViewHolder;
+
+public class ModDetailAssignmentAdapter extends BaseExpandableListAdapter {
+
+ private Modules.Module mModule = null;
+
+ @Override
+ public String getChild(int groupPosition, int childPosititon) {
+ StringBuilder sb = new StringBuilder();
+ for (String s : this.getGroup(groupPosition).getUrls())
+ {
+ sb.append(s);
+ sb.append("\n");
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ @Override
+ public View getChildView(int groupPosition, final int childPosition,
+ boolean isLastChild, View convertView, ViewGroup parent) {
+
+ final String childText = getChild(groupPosition, childPosition);
+
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.list_all_string, parent, false);
+ }
+
+ StringViewHolder itemHolder = new StringViewHolder(convertView);
+ itemHolder.mString.setText(childText);
+
+ return convertView;
+ }
+
+ @Override
+ public int getChildrenCount(int groupPosition) {
+ return 1;
+ }
+
+ @Override
+ public Assignment getGroup(int groupPosition) {
+ if (this.mModule != null && this.mModule.assignments != null)
+ return this.mModule.assignments.get(groupPosition);
+ else
+ return null;
+ }
+
+ @Override
+ public int getGroupCount() {
+ if (this.mModule != null && this.mModule.assignments != null)
+ return this.mModule.assignments.size();
+ else
+ return 0;
+ }
+
+ @Override
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ @Override
+ public View getGroupView(int groupPosition, boolean isExpanded,
+ View convertView, ViewGroup parent) {
+ Assignment assignment = getGroup(groupPosition);
+ if (convertView == null) {
+ convertView = LayoutInflater.from(parent.getContext())
+ .inflate(R.layout.list_all_items, parent, false);
+ }
+
+ ItemViewHolder itemHolder = new ItemViewHolder(convertView);
+ itemHolder.mTitle.setText(assignment.getTitle());
+ if(assignment.isOpen())
+ itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.open));
+ else
+ itemHolder.mSubLeft.setText(itemHolder.mView.getResources().getText(R.string.close));
+ itemHolder.mSubRight.setText(Conversion.getModifiedDateTime(assignment.getDueDate()));
+
+ return convertView;
+ }
+
+ @Override
+ public boolean hasStableIds() {
+ return false;
+ }
+
+ @Override
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return false;
+ }
+
+ public void setModule(Modules.Module module) {
+ this.mModule = module;
+ this.setModule();
+ }
+
+ public void setModule() {
+ this.notifyDataSetChanged();
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java
new file mode 100644
index 0000000..e876ea6
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailAssignmentFragment.java
@@ -0,0 +1,106 @@
+package de.sebse.fuplanner.fragments.moddetails;
+
+
+import android.content.Context;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.Fragment;
+import android.support.v4.widget.SwipeRefreshLayout;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ExpandableListView;
+
+import de.sebse.fuplanner.MainActivity;
+import de.sebse.fuplanner.R;
+import de.sebse.fuplanner.services.KVV.KVV;
+import de.sebse.fuplanner.services.KVV.types.Modules;
+import de.sebse.fuplanner.tools.logging.Logger;
+
+/**
+ * A simple {@link Fragment} subclass.
+ * Use the {@link ModDetailAssignmentFragment#newInstance} factory method to
+ * create an instance of this fragment.
+ */
+public class ModDetailAssignmentFragment extends Fragment {
+ // TODO: Rename parameter arguments, choose names that match
+ // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
+ private static final String ARG_POSITION = "itemPosition";
+
+ // TODO: Rename and change types of parameters
+ private int mItemPos;
+ private Logger log = new Logger(this);
+ private ModDetailAssignmentAdapter adapter;
+ private SwipeRefreshLayout swipeLayout;
+
+
+ public ModDetailAssignmentFragment() {
+ // Required empty public constructor
+ }
+
+ /**
+ * Use this factory method to create a new instance of
+ * this fragment using the provided parameters.
+ *
+ * @param itemPosition Item position in module list.
+ * @return A new instance of fragment ModDetailAnnounceFragment.
+ */
+ // TODO: Rename and change types and number of parameters
+ public static ModDetailAssignmentFragment newInstance(int itemPosition) {
+ ModDetailAssignmentFragment fragment = new ModDetailAssignmentFragment();
+ Bundle args = new Bundle();
+ args.putInt(ARG_POSITION, itemPosition);
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ if (getArguments() != null) {
+ mItemPos = getArguments().getInt(ARG_POSITION);
+ }
+ }
+
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ View view = inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
+ // Set the adapter
+ Context context = view.getContext();
+ ExpandableListView expandableListView = view.findViewById(R.id.list);
+ //expandableListView.setLayoutManager(new LinearLayoutManager(context));
+ adapter = new ModDetailAssignmentAdapter();
+ expandableListView.setAdapter(adapter);
+
+ // Getting SwipeContainerLayout
+ swipeLayout = view.findViewById(R.id.swipe_container);
+ // Adding Listener
+ swipeLayout.setOnRefreshListener(() -> refresh(true));
+ refresh(false);
+
+ return view;
+ }
+
+ private void refresh(boolean forceRefresh) {
+ if (getActivity() != null) {
+ KVV kvv = ((MainActivity) getActivity()).getKVV();
+ kvv.getModuleList((Modules success) -> {
+ Modules.Module module = success.get(mItemPos);
+ adapter.setModule(module);
+ kvv.getModuleAssignments(module, success1 -> {
+ adapter.setModule();
+ swipeLayout.setRefreshing(false);
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ });
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ }, forceRefresh);
+ }
+ }
+
+}
diff --git a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java
index 01cf213..a03c5b4 100644
--- a/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java
+++ b/app/src/main/java/de/sebse/fuplanner/fragments/moddetails/ModDetailOverviewFragment.java
@@ -94,8 +94,14 @@ public class ModDetailOverviewFragment extends Fragment {
adapter.setModule();
if (pair.second)
swipeLayout.setRefreshing(false);
- }, error -> log.e(error));
- }, error -> log.e(error), forceRefresh);
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ });
+ }, error -> {
+ swipeLayout.setRefreshing(false);
+ log.e(error);
+ }, forceRefresh);
}
}
diff --git a/app/src/main/java/de/sebse/fuplanner/services/KVV/KVV.java b/app/src/main/java/de/sebse/fuplanner/services/KVV/KVV.java
index 4ac3eaf..d48d15c 100644
--- a/app/src/main/java/de/sebse/fuplanner/services/KVV/KVV.java
+++ b/app/src/main/java/de/sebse/fuplanner/services/KVV/KVV.java
@@ -10,6 +10,7 @@ import java.util.HashMap;
import de.sebse.fuplanner.services.KVV.types.LoginToken;
import de.sebse.fuplanner.services.KVV.types.Modules;
+import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
@@ -23,8 +24,10 @@ public class KVV {
private boolean isUpdating;
private ArrayList updatingList;
private HashMap addons = new HashMap<>();
+ private Logger log = new Logger(this);
public KVV(Context context) {
+ log.d("new kvv");
this.context = context;
this.isUpdating = false;
this.updatingList = new ArrayList<>();
@@ -42,7 +45,7 @@ public class KVV {
lastToken = null;
KVVModuleList modules = (KVVModuleList) addons.get("modules");
if (modules != null) {
- modules.deleteModules(this.context);
+ modules.deleteModulesOffline(this.context);
}
addons.clear();
}
@@ -118,7 +121,7 @@ public class KVV {
private NetworkCallback saveOnCallback(KVVModuleList modules, NetworkCallback callback){
return (success -> {
try {
- modules.saveModules(this.context);
+ modules.saveModulesOffline(this.context);
} catch (IOException e) {
e.printStackTrace();
}
diff --git a/app/src/main/java/de/sebse/fuplanner/services/KVV/KVVModuleList.java b/app/src/main/java/de/sebse/fuplanner/services/KVV/KVVModuleList.java
index aa3a10d..da5a7fb 100644
--- a/app/src/main/java/de/sebse/fuplanner/services/KVV/KVVModuleList.java
+++ b/app/src/main/java/de/sebse/fuplanner/services/KVV/KVVModuleList.java
@@ -23,6 +23,7 @@ import de.sebse.fuplanner.services.KVV.types.Gradebook;
import de.sebse.fuplanner.services.KVV.types.Lecturer;
import de.sebse.fuplanner.services.KVV.types.LoginToken;
import de.sebse.fuplanner.services.KVV.types.Modules;
+import de.sebse.fuplanner.tools.AssignmentList;
import de.sebse.fuplanner.tools.AsyncQueue;
import de.sebse.fuplanner.tools.EventList;
import de.sebse.fuplanner.tools.Regex;
@@ -44,7 +45,9 @@ public class KVVModuleList extends HTTPService {
super(context);
this.token = token;
try {
- this.moduleList = Modules.load(context);
+ Modules modules = Modules.load(context);
+ if (token == null || modules.getUsername().equals(token.getUsername()))
+ this.moduleList = modules;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
@@ -56,7 +59,9 @@ public class KVVModuleList extends HTTPService {
public void getModuleList(final NetworkCallback callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
+ log.d("getModuleList");
queueModuleDetails.add("list", () -> {
+ log.d("getModuleList start", forceRefresh);
if (this.moduleList != null && !forceRefresh) {
callback.onResponse(this.moduleList);
queueModuleDetails.next("list");
@@ -66,18 +71,22 @@ public class KVVModuleList extends HTTPService {
this.moduleList = success;
callback.onResponse(this.moduleList);
queueModuleDetails.next("list");
- }, errorCallback);
+ }, queueModuleDetails.check("list", errorCallback));
});
}
- public void getModuleListUpgrade(final NetworkCallback callback, final NetworkErrorCallback errorCallback) {
+ private void getModuleListUpgrade(final NetworkCallback callback, final NetworkErrorCallback errorCallback) {
+ if (token == null) {
+ errorCallback.onError(new NetworkError(101105, 500, "Currently running in offline mode!"));
+ return;
+ }
get("https://kvv.imp.fu-berlin.de/direct/site.json", token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101101, 403, "No module list retrieved!"));
return;
}
- Modules modules = new Modules();
+ Modules modules = new Modules(token.getUsername());
try {
JSONObject json = new JSONObject(body);
JSONArray sites = json.getJSONArray("site_collection");
@@ -112,12 +121,12 @@ public class KVVModuleList extends HTTPService {
}, error -> errorCallback.onError(new NetworkError(101104, error.networkResponse.statusCode, "Cannot get module list!")));
}
- public void deleteModules(Context context) {
+ public void deleteModulesOffline(Context context) {
if (this.moduleList != null)
this.moduleList.delete(context);
}
- public void saveModules(Context context) throws IOException {
+ public void saveModulesOffline(Context context) throws IOException {
if (this.moduleList != null)
this.moduleList.save(context);
}
@@ -134,11 +143,11 @@ public class KVVModuleList extends HTTPService {
public void getModuleDetails(Modules.Module module, final NetworkCallback> callback, final NetworkErrorCallback errorCallback, boolean forceRefresh) {
AtomicInteger returns = new AtomicInteger(0);
AtomicReference lastError = new AtomicReference<>(null);
- final int items = 4;
+ final AtomicInteger items = new AtomicInteger(0);
NetworkCallback successCb = success -> {
returns.getAndIncrement();
callback.onResponse(Pair.create(module, false));
- if (returns.get() == items) {
+ if (returns.get() == items.get()) {
callback.onResponse(Pair.create(module, true));
if (lastError.get() != null)
errorCallback.onError(lastError.get());
@@ -147,7 +156,7 @@ public class KVVModuleList extends HTTPService {
NetworkErrorCallback errorCb = error -> {
lastError.set(error);
returns.getAndIncrement();
- if (returns.get() == items) {
+ if (returns.get() == items.get()) {
callback.onResponse(Pair.create(module, true));
if (lastError.get() != null)
errorCallback.onError(lastError.get());
@@ -159,8 +168,7 @@ public class KVVModuleList extends HTTPService {
() -> this.getAnnouncements(module, successCb, errorCb, forceRefresh),
() -> this.getGradebook(module, successCb, errorCb, forceRefresh)
};
- //noinspection ConstantConditions
- if (methods.length != items) throw new AssertionError();
+ items.set(methods.length);
for (Runnable method: methods) {
method.run();
}
@@ -182,12 +190,15 @@ public class KVVModuleList extends HTTPService {
module.announcements = success;
callback.onResponse(module);
queueModuleDetails.next(module.getID());
- }, errorCallback);
+ }, queueModuleDetails.check(module.getID(), errorCallback));
});
}
private void getAnnouncementsUpgrade(String ID, final NetworkCallback> callback, final NetworkErrorCallback errorCallback) {
- //log.d("SITE GET URL", String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID));
+ if (token == null) {
+ errorCallback.onError(new NetworkError(101204, 500, "Currently running in offline mode!"));
+ return;
+ }
get(String.format("https://kvv.imp.fu-berlin.de/direct/announcement/site/%s.json?n=999999&d=999999999", ID), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -233,18 +244,22 @@ public class KVVModuleList extends HTTPService {
module.assignments = success;
callback.onResponse(module);
queueModuleDetails.next(module.getID());
- }, errorCallback);
+ }, queueModuleDetails.check(module.getID(), errorCallback));
});
}
- private void getAssignmentsUpgrade(String ID, final NetworkCallback> callback, final NetworkErrorCallback errorCallback) {
+ private void getAssignmentsUpgrade(String ID, final NetworkCallback callback, final NetworkErrorCallback errorCallback) {
+ if (token == null) {
+ errorCallback.onError(new NetworkError(101304, 500, "Currently running in offline mode!"));
+ return;
+ }
get(String.format("https://kvv.imp.fu-berlin.de/direct/assignment/site/%s.json", ID), token.getCookies(), response ->{
String body = response.getParsed();
if (body == null) {
errorCallback.onError(new NetworkError(101301, 403, "No assignments retrieved!"));
return;
}
- ArrayList assignments = new ArrayList<>();
+ AssignmentList assignments = new AssignmentList();
try {
JSONObject json = new JSONObject(body);
JSONArray sites = json.getJSONArray("assignment_collection");
@@ -272,7 +287,7 @@ public class KVVModuleList extends HTTPService {
assignments.add(0, new Assignment(id, title, dueTime, gradebookItemName, gradeScale, urls));
}
} catch (JSONException e) {
- errorCallback.onError(new NetworkError(101306, 403, "Cannot parse announcements!"));
+ errorCallback.onError(new NetworkError(101302, 403, "Cannot parse announcements!"));
return;
}
callback.onResponse(assignments);
@@ -297,12 +312,15 @@ public class KVVModuleList extends HTTPService {
module.events = success;
callback.onResponse(module);
queueModuleDetails.next(module.getID());
- }, errorCallback);
+ }, queueModuleDetails.check(module.getID(), errorCallback));
});
}
private void getEventsUpgrade(String ID, final NetworkCallback callback, final NetworkErrorCallback errorCallback) {
- //https://kvv.imp.fu-berlin.de/direct/calendar/site/91c6e9cc-58eb-486d-ab99-a22a40997d1b.json
+ if (token == null) {
+ errorCallback.onError(new NetworkError(101404, 500, "Currently running in offline mode!"));
+ return;
+ }
get(String.format("https://kvv.imp.fu-berlin.de/direct/calendar/site/%s.json", ID), token.getCookies(), response -> {
String body = response.getParsed();
if (body == null) {
@@ -348,11 +366,15 @@ public class KVVModuleList extends HTTPService {
module.gradebook = success;
callback.onResponse(module);
queueModuleDetails.next(module.getID());
- }, errorCallback);
+ }, queueModuleDetails.check(module.getID(), errorCallback));
});
}
private void getGradebookUpgrade(String ID, final NetworkCallback> callback, final NetworkErrorCallback errorCallback) {
+ if (token == null) {
+ errorCallback.onError(new NetworkError(101104, 500, "Currently running in offline mode!"));
+ return;
+ }
get(String.format("https://kvv.imp.fu-berlin.de/direct/gradebook/site/%s.json", ID ), token.getCookies(), response ->{
String body = response.getParsed();
if (body == null) {
@@ -365,22 +387,20 @@ public class KVVModuleList extends HTTPService {
JSONArray sites = json.getJSONArray("assignments");
for (int i = 0; i < sites.length(); i++) {
- //log.d("gradebook FOUND!", i);
JSONObject site = sites.getJSONObject(i);
String grade = site.optString("grade", null);
String itemName = site.optString("itemName", null);
double maxPoints = site.optDouble("points", -1);
- //log.d("Gradebook:",itemName, grade, maxPoints);
gradebook.add(0, new Gradebook(itemName, grade, maxPoints));
}
}catch (JSONException e) {
- errorCallback.onError(new NetworkError(101504, 403, "Cannot parse gradebook for announcements!"));
+ errorCallback.onError(new NetworkError(101502, 403, "Cannot parse gradebook for announcements!"));
return;
}
callback.onResponse(gradebook);
- }, error -> errorCallback.onError(new NetworkError(101505, error.networkResponse.statusCode, "Cannot get gradebook for assignments!")));
+ }, error -> errorCallback.onError(new NetworkError(101503, error.networkResponse.statusCode, "Cannot get gradebook for assignments!")));
}
diff --git a/app/src/main/java/de/sebse/fuplanner/services/KVV/types/Modules.java b/app/src/main/java/de/sebse/fuplanner/services/KVV/types/Modules.java
index 42b8e51..7db9dcb 100644
--- a/app/src/main/java/de/sebse/fuplanner/services/KVV/types/Modules.java
+++ b/app/src/main/java/de/sebse/fuplanner/services/KVV/types/Modules.java
@@ -13,6 +13,7 @@ import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import de.sebse.fuplanner.tools.AssignmentList;
import de.sebse.fuplanner.tools.Compare;
import de.sebse.fuplanner.tools.EventList;
import de.sebse.fuplanner.tools.Regex;
@@ -26,10 +27,12 @@ import de.sebse.fuplanner.tools.logging.Logger;
public class Modules implements Iterable, Serializable {
private final SortedModuleList list;
private String latestSemester = null;
+ private String username = null;
private transient Logger log = new Logger(this);
private static final String FILE_NAME = "ModuleListSaving";
- public Modules() {
+ public Modules(String username) {
+ this.username = username;
this.list = new SortedModuleList();
}
@@ -174,6 +177,10 @@ public class Modules implements Iterable, Serializable {
context.deleteFile(FILE_NAME);
}
+ public String getUsername() {
+ return username;
+ }
+
public class Module implements Serializable {
public final String semester;
public final HashSet lvNumber;
@@ -183,7 +190,7 @@ public class Modules implements Iterable, Serializable {
public final String description;
private final String ID;
public ArrayList announcements;
- public ArrayList assignments;
+ public AssignmentList assignments;
public EventList events;
public ArrayList gradebook;
diff --git a/app/src/main/java/de/sebse/fuplanner/tools/AssignmentList.java b/app/src/main/java/de/sebse/fuplanner/tools/AssignmentList.java
new file mode 100644
index 0000000..82292ac
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/tools/AssignmentList.java
@@ -0,0 +1,19 @@
+package de.sebse.fuplanner.tools;
+
+import de.sebse.fuplanner.services.KVV.types.Assignment;
+import de.sebse.fuplanner.tools.logging.Logger;
+
+public class AssignmentList extends DateSortedList {
+
+ @Override
+ long getDateByItem(Assignment item) {
+ Logger log = new Logger(this);
+ log.d(item.getTitle(), Conversion.getModifiedDateTime(item.getDueDate()));
+ return item.getDueDate();
+ }
+
+ @Override
+ public boolean reversed() {
+ return true;
+ }
+}
diff --git a/app/src/main/java/de/sebse/fuplanner/tools/AsyncQueue.java b/app/src/main/java/de/sebse/fuplanner/tools/AsyncQueue.java
index 2bc56c6..a65cba8 100644
--- a/app/src/main/java/de/sebse/fuplanner/tools/AsyncQueue.java
+++ b/app/src/main/java/de/sebse/fuplanner/tools/AsyncQueue.java
@@ -3,6 +3,7 @@ package de.sebse.fuplanner.tools;
import java.util.HashMap;
import java.util.LinkedList;
+import de.sebse.fuplanner.tools.logging.Logger;
import de.sebse.fuplanner.tools.network.NetworkCallback;
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
diff --git a/app/src/main/java/de/sebse/fuplanner/tools/DateSortedList.java b/app/src/main/java/de/sebse/fuplanner/tools/DateSortedList.java
new file mode 100644
index 0000000..2b5d020
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/tools/DateSortedList.java
@@ -0,0 +1,108 @@
+package de.sebse.fuplanner.tools;
+
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Iterator;
+
+import de.sebse.fuplanner.services.KVV.types.Event;
+
+public abstract class DateSortedList extends ArrayList {
+ private int split = -1;
+
+ public T getPast(int index) {
+ if (split < 0)
+ sort();
+ if (index >= split)
+ throw new ArrayIndexOutOfBoundsException(String.format("Index %d out of bounds! Only %d past events found!", index, split));
+ if (reversed())
+ index = sizePast() - index - 1;
+ return this.get(index);
+ }
+
+ public T getUpcoming(int index) {
+ if (split < 0)
+ sort();
+ index += split;
+ if (index >= this.size())
+ throw new ArrayIndexOutOfBoundsException(String.format("Index %d out of bounds! Only %d upcoming events found!", index-split, this.size()-split));
+ if (reversed())
+ index = sizeUpcoming() - index - 1;
+ return this.get(index);
+ }
+
+ @Override
+ public T get(int index) {
+ if (split < 0)
+ sort();
+ if (reversed())
+ index = size() - index - 1;
+ return super.get(index);
+ }
+
+ public int sizePast() {
+ if (split < 0)
+ sort();
+ return split;
+ }
+
+ public int sizeUpcoming() {
+ if (split < 0)
+ sort();
+ return this.size()-split;
+ }
+
+ public boolean add(T event) {
+ split = -1;
+ return super.add(event);
+ }
+
+ public void sort() {
+
+ Collections.sort(this, ((e1, e2) -> Long.compare(getDateByItem(e1), getDateByItem(e2))));
+ long now = System.currentTimeMillis();
+ split = 0;
+ for (T event: this) {
+ if (getDateByItem(event) < now)
+ split++;
+ else
+ break;
+ }
+ }
+
+ public Iterator getEventsOfMonth(int year, int month) {
+ if (split < 0)
+ sort();
+ final int[] i = {0};
+ Calendar minC = Calendar.getInstance();
+ minC.set(year, month-1, 1, 0, 0);
+ Calendar maxC = Calendar.getInstance();
+ maxC.set(year, month, 1, 0, 0);
+ for (; i[0] < this.size(); i[0]++) {
+ if (getDateByItem(this.get(i[0])) > minC.getTimeInMillis()) {
+ break;
+ }
+ }
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return i[0] < DateSortedList.this.size() && getDateByItem(DateSortedList.this.get(i[0])) < maxC.getTimeInMillis();
+ }
+
+ @Override
+ public T next() {
+ if (hasNext()) {
+ return DateSortedList.this.get(i[0]++);
+ } else {
+ return null;
+ }
+ }
+ };
+ }
+
+ public boolean reversed() {
+ return false;
+ }
+
+ abstract long getDateByItem(T item);
+}
diff --git a/app/src/main/java/de/sebse/fuplanner/tools/EventList.java b/app/src/main/java/de/sebse/fuplanner/tools/EventList.java
index c233f0a..b7aabd2 100644
--- a/app/src/main/java/de/sebse/fuplanner/tools/EventList.java
+++ b/app/src/main/java/de/sebse/fuplanner/tools/EventList.java
@@ -1,88 +1,11 @@
package de.sebse.fuplanner.tools;
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.Iterator;
-
import de.sebse.fuplanner.services.KVV.types.Event;
-public class EventList extends ArrayList {
- private int split = 0;
+public class EventList extends DateSortedList {
- public Event getPast(int index) {
- if (split < 0)
- sort();
- if (index >= split)
- throw new ArrayIndexOutOfBoundsException(String.format("Index %d out of bounds! Only %d past events found!", index, split));
- return this.get(index);
- }
-
- public Event getUpcoming(int index) {
- if (split < 0)
- sort();
- index += split;
- if (index >= this.size())
- throw new ArrayIndexOutOfBoundsException(String.format("Index %d out of bounds! Only %d upcoming events found!", index-split, this.size()-split));
- return this.get(index);
- }
-
- public int sizePast() {
- if (split < 0)
- sort();
- return split;
- }
-
- public int sizeUpcoming() {
- if (split < 0)
- sort();
- return this.size()-split;
- }
-
- public boolean add(Event event) {
- split = -1;
- return super.add(event);
- }
-
- public void sort() {
- Collections.sort(this, ((e1, e2) -> Long.compare(e1.getEndDate(), e2.getEndDate())));
- long now = System.currentTimeMillis();
- split = 0;
- for (Event event : this) {
- if (event.getEndDate() < now)
- split++;
- else
- break;
- }
- }
-
- public Iterator getEventsOfMonth(int year, int month) {
- if (split < 0)
- sort();
- final int[] i = {0};
- Calendar minC = Calendar.getInstance();
- minC.set(year, month-1, 1, 0, 0);
- Calendar maxC = Calendar.getInstance();
- maxC.set(year, month, 1, 0, 0);
- for (; i[0] < this.size(); i[0]++) {
- if (this.get(i[0]).getEndDate() > minC.getTimeInMillis()) {
- break;
- }
- }
- return new Iterator() {
- @Override
- public boolean hasNext() {
- return i[0] < EventList.this.size() && EventList.this.get(i[0]).getEndDate() < maxC.getTimeInMillis();
- }
-
- @Override
- public Event next() {
- if (hasNext()) {
- return EventList.this.get(i[0]++);
- } else {
- return null;
- }
- }
- };
+ @Override
+ long getDateByItem(Event item) {
+ return item.getEndDate();
}
}
diff --git a/app/src/main/java/de/sebse/fuplanner/tools/ui/StringViewHolder.java b/app/src/main/java/de/sebse/fuplanner/tools/ui/StringViewHolder.java
new file mode 100644
index 0000000..65aa3c7
--- /dev/null
+++ b/app/src/main/java/de/sebse/fuplanner/tools/ui/StringViewHolder.java
@@ -0,0 +1,20 @@
+package de.sebse.fuplanner.tools.ui;
+
+import android.view.View;
+import android.widget.TextView;
+
+import de.sebse.fuplanner.R;
+
+public class StringViewHolder extends CustomViewHolder {
+ public final TextView mString;
+
+ public StringViewHolder(View view) {
+ super(view);
+ mString = view.findViewById(R.id.string);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + " '" + mString.getText() + "'";
+ }
+}
diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml
index 323a10f..eb9b474 100644
--- a/app/src/main/res/layout/fragment_login.xml
+++ b/app/src/main/res/layout/fragment_login.xml
@@ -48,13 +48,22 @@
+
+
diff --git a/app/src/main/res/layout/fragment_mod_detail_announce.xml b/app/src/main/res/layout/fragment_mod_detail_announce.xml
index 99b4da7..5ecf219 100644
--- a/app/src/main/res/layout/fragment_mod_detail_announce.xml
+++ b/app/src/main/res/layout/fragment_mod_detail_announce.xml
@@ -1,14 +1,19 @@
-
-
-
-
+
-
-
\ No newline at end of file
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ app:layoutManager="android.support.v7.widget.LinearLayoutManager"
+ tools:context=".fragments.moddetails.ModDetailAnnounceFragment"
+ tools:listitem="@layout/list_all_caption" />
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/list_all_string.xml b/app/src/main/res/layout/list_all_string.xml
new file mode 100644
index 0000000..ee17e94
--- /dev/null
+++ b/app/src/main/res/layout/list_all_string.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 79fda9e..61fb7b8 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -34,4 +34,5 @@
Hello blank fragment
+ Enter Offline Mode (%1$s)
diff --git a/build.gradle b/build.gradle
index ad6a928..be59a9b 100644
--- a/build.gradle
+++ b/build.gradle
@@ -18,6 +18,12 @@ allprojects {
jcenter()
google()
}
+
+ gradle.projectsEvaluated {
+ tasks.withType(JavaCompile) {
+ options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
+ }
+ }
}
task clean(type: Delete) {