Module Detail Overview Implementation #2
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
@@ -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.0'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.1'
|
||||
implementation 'com.android.volley:volley:1.0.0'
|
||||
//noinspection GradleDependency
|
||||
implementation 'com.google.android.gms:play-services-auth:15.0.0'
|
||||
@@ -45,5 +45,6 @@ dependencies {
|
||||
implementation 'org.jbundle.util.osgi.wrapped:org.jbundle.util.osgi.wrapped.org.apache.http.client:4.1.2'
|
||||
implementation 'com.android.support:support-v4:27.1.1'
|
||||
implementation 'org.jetbrains:annotations-java5:15.0'
|
||||
implementation 'com.ms-square:expandableTextView:0.1.4'
|
||||
implementation files('libs/jericho-html-3.4.jar')
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
@@ -22,17 +22,11 @@ import de.sebse.fuplanner.fragments.LoginFragment;
|
||||
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
||||
import de.sebse.fuplanner.fragments.ModulesFragment;
|
||||
import de.sebse.fuplanner.fragments.StartupFragment;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.ConnectedListener;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.Credentials;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.CredentialsListener;
|
||||
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
||||
import de.sebse.fuplanner.services.KVV.KVV;
|
||||
import de.sebse.fuplanner.services.KVV.LoginToken;
|
||||
import de.sebse.fuplanner.services.KVV.Modules;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
public class MainActivity extends AppCompatActivity
|
||||
implements NavigationView.OnNavigationItemSelectedListener,
|
||||
@@ -55,7 +49,7 @@ public class MainActivity extends AppCompatActivity
|
||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
||||
drawer.setDrawerListener(toggle);
|
||||
drawer.addDrawerListener(toggle);
|
||||
toggle.syncState();
|
||||
|
||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
||||
@@ -75,35 +69,23 @@ public class MainActivity extends AppCompatActivity
|
||||
findViewById(R.id.app_bar_layout).setVisibility(View.GONE);
|
||||
|
||||
|
||||
this.getGoogleAuth().connect(new ConnectedListener() {
|
||||
@Override
|
||||
public void connected() {
|
||||
this.getGoogleAuth().connect(() -> {
|
||||
// getGoogleAuth().setLoginState("seedorf96", "m&gcwBaT@");
|
||||
getGoogleAuth().getLoginState(new CredentialsListener() {
|
||||
@Override
|
||||
public void onCredentials(final Credentials credentials) {
|
||||
getGoogleAuth().getLoginState(credentials -> {
|
||||
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
changeLoginState(null);
|
||||
return;
|
||||
}
|
||||
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), new NetworkCallback<LoginToken>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull LoginToken success) {
|
||||
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
changeLoginState(credentials);
|
||||
}
|
||||
}, new NetworkErrorCallback() {
|
||||
@Override
|
||||
public void onError(NetworkError error) {
|
||||
}, error -> {
|
||||
log.e(error);
|
||||
MainActivity.this.getKVV().endUpdate();
|
||||
changeLoginState(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -159,14 +141,11 @@ public class MainActivity extends AppCompatActivity
|
||||
break;
|
||||
case R.id.nav_logout:
|
||||
this.getKVV().logout();
|
||||
this.getGoogleAuth().getLoginState(new CredentialsListener() {
|
||||
@Override
|
||||
public void onCredentials(Credentials credentials) {
|
||||
this.getGoogleAuth().getLoginState(credentials -> {
|
||||
if (credentials != null) {
|
||||
MainActivity.this.getGoogleAuth().deleteLoginState(credentials.getUsername(), credentials.getPassword());
|
||||
}
|
||||
MainActivity.this.changeLoginState(null);
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -236,9 +215,7 @@ public class MainActivity extends AppCompatActivity
|
||||
navigationView.getMenu().clear();
|
||||
navigationView.inflateMenu(R.menu.activity_main_drawer_login);
|
||||
navigationView.setCheckedItem(R.id.nav_modules);
|
||||
getKVV().getModuleList(new NetworkCallback<Modules>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Modules success) {
|
||||
getKVV().getModuleList(success -> {
|
||||
log.d("Modules.get", success.size());
|
||||
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
|
||||
int i = 0;
|
||||
@@ -252,13 +229,7 @@ public class MainActivity extends AppCompatActivity
|
||||
});
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}, new NetworkErrorCallback() {
|
||||
@Override
|
||||
public void onError(NetworkError error) {
|
||||
log.d("Modules.error", error);
|
||||
}
|
||||
});
|
||||
}, error -> log.d("Modules.error", error));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,16 +251,8 @@ public class MainActivity extends AppCompatActivity
|
||||
@Override
|
||||
public void onModulesFragmentInteraction(final int itemPosition) {
|
||||
log.d("Item clicked", itemPosition);
|
||||
getKVV().getModuleList(new NetworkCallback<Modules>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Modules success) {
|
||||
log.d(success.get(itemPosition).title);
|
||||
}
|
||||
}, new NetworkErrorCallback() {
|
||||
@Override
|
||||
public void onError(NetworkError error) {
|
||||
getKVV().getModuleList(success -> log.d(success.get(itemPosition).title), error -> {
|
||||
// TODO
|
||||
}
|
||||
});
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
|
||||
@@ -5,7 +5,6 @@ import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -16,11 +15,7 @@ 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.LoginToken;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
@@ -63,16 +58,14 @@ public class LoginFragment extends Fragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
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(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
btn_login.setOnClickListener(view -> {
|
||||
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
|
||||
R.style.FUTheme_Dialog);
|
||||
progressDialog.setIndeterminate(true);
|
||||
@@ -92,9 +85,7 @@ public class LoginFragment extends Fragment {
|
||||
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, new NetworkCallback<LoginToken>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull LoginToken success) {
|
||||
kvv.login(username, password, success -> {
|
||||
progressDialog.dismiss();
|
||||
log.d("success", success.toString());
|
||||
gauth.setLoginState(username, password);
|
||||
@@ -102,17 +93,12 @@ public class LoginFragment extends Fragment {
|
||||
Credentials cred = new Credentials(username, password);
|
||||
LoginFragment.this.mListener.onLoginFragmentInteraction(cred);
|
||||
}
|
||||
}
|
||||
}, new NetworkErrorCallback() {
|
||||
@Override
|
||||
public void onError(NetworkError error) {
|
||||
}, error -> {
|
||||
progressDialog.dismiss();
|
||||
log.e("error", error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -13,11 +13,7 @@ import android.view.ViewGroup;
|
||||
|
||||
import de.sebse.fuplanner.MainActivity;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.services.KVV.Modules;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
/**
|
||||
* A fragment representing a list of Items.
|
||||
@@ -75,18 +71,10 @@ public class ModulesFragment extends Fragment {
|
||||
|
||||
|
||||
if (getActivity() != null) {
|
||||
((MainActivity) getActivity()).getKVV().getModuleList(new NetworkCallback<Modules>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Modules success) {
|
||||
((MainActivity) getActivity()).getKVV().getModuleList(success -> {
|
||||
log.d(success);
|
||||
adapter.setModules(success);
|
||||
}
|
||||
}, new NetworkErrorCallback() {
|
||||
@Override
|
||||
public void onError(NetworkError error) {
|
||||
Log.e("ModFrag", error.toString());
|
||||
}
|
||||
});
|
||||
}, error -> Log.e("ModFrag", error.toString()));
|
||||
}
|
||||
}
|
||||
return view;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.sebse.fuplanner.fragments;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -31,30 +32,29 @@ public class ModulesRecyclerViewAdapter extends RecyclerView.Adapter<ModulesRecy
|
||||
this.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.fragment_modules, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
||||
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||
if (mValues == null)
|
||||
return;
|
||||
position = holder.getAdapterPosition();
|
||||
holder.mItemPosition = position;
|
||||
holder.mIdView.setText(mValues.get(position).semester);
|
||||
holder.mContentView.setText(mValues.get(position).title);
|
||||
|
||||
holder.mView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
holder.mView.setOnClickListener(v -> {
|
||||
if (null != mListener) {
|
||||
// Notify the active callbacks interface (the activity, if the
|
||||
// fragment is attached to one) that an item has been selected.
|
||||
mListener.onModulesFragmentInteraction(holder.mItemPosition);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ public class ModulesRecyclerViewAdapter extends RecyclerView.Adapter<ModulesRecy
|
||||
public ViewHolder(View view) {
|
||||
super(view);
|
||||
mView = view;
|
||||
mIdView = (TextView) view.findViewById(R.id.id);
|
||||
mContentView = (TextView) view.findViewById(R.id.content);
|
||||
mIdView = view.findViewById(R.id.id);
|
||||
mContentView = view.findViewById(R.id.content);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package de.sebse.fuplanner.fragments;
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
@@ -13,9 +11,6 @@ import de.sebse.fuplanner.R;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Activities that contain this fragment must implement the
|
||||
* {@link StartupFragment.OnStartupFragmentInteractionListener} interface
|
||||
* to handle interaction events.
|
||||
* Use the {@link StartupFragment#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package de.sebse.fuplanner.fragments.moddetails;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||
|
||||
@@ -2,6 +2,7 @@ package de.sebse.fuplanner.fragments.moddetails;
|
||||
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -54,7 +55,7 @@ public class ModDetailAnnounceFragment extends Fragment {
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
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);
|
||||
|
||||
@@ -31,7 +31,6 @@ public class ModDetailFragment extends Fragment {
|
||||
private int mItemPos;
|
||||
|
||||
private OnModuleDetailFragmentInteractionListener mListener;
|
||||
private ModDetailAdapter adapterViewPager;
|
||||
private Logger log = new Logger(this);
|
||||
|
||||
public ModDetailFragment() {
|
||||
@@ -71,8 +70,8 @@ public class ModDetailFragment extends Fragment {
|
||||
log.d("on create view");
|
||||
View v = inflater.inflate(R.layout.fragment_mod_detail, container, false);
|
||||
|
||||
ViewPager vpPager = (ViewPager) v.findViewById(R.id.vpPager);
|
||||
adapterViewPager = new ModDetailAdapter(getFragmentManager(), mItemPos, getContext());
|
||||
ViewPager vpPager = v.findViewById(R.id.vpPager);
|
||||
ModDetailAdapter adapterViewPager = new ModDetailAdapter(getFragmentManager(), mItemPos, getContext());
|
||||
vpPager.setAdapter(adapterViewPager);
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
package de.sebse.fuplanner.fragments.moddetails;
|
||||
|
||||
import android.icu.text.DateFormat;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import com.ms.square.android.expandabletextview.ExpandableTextView;
|
||||
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.fragments.ModulesFragment;
|
||||
import de.sebse.fuplanner.fragments.ModulesRecyclerViewAdapter;
|
||||
import de.sebse.fuplanner.services.KVV.Announcement;
|
||||
import de.sebse.fuplanner.services.KVV.Assignment;
|
||||
import de.sebse.fuplanner.services.KVV.Modules;
|
||||
import de.sebse.fuplanner.tools.Conversion;
|
||||
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
||||
|
||||
public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
||||
private static final int TYPE_HEADER = 0;
|
||||
private static final int TYPE_DESCRIPTION = 1;
|
||||
private static final int TYPE_ITEM = 2;
|
||||
private static final int TYPE_SHOW_MORE = 3;
|
||||
|
||||
private Modules.Module mValue;
|
||||
//private final ModulesFragment.OnModulesFragmentInteractionListener mListener;
|
||||
|
||||
@@ -39,18 +40,22 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
||||
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view;
|
||||
switch (viewType) {
|
||||
case 0:
|
||||
case TYPE_HEADER:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_caption, parent, false);
|
||||
return new HeaderViewHolder(view);
|
||||
case 1:
|
||||
case TYPE_DESCRIPTION:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_moddetails_description, parent, false);
|
||||
return new DescriptionViewHolder(view);
|
||||
case 2:
|
||||
case TYPE_ITEM:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_moddetails_announcements, parent, false);
|
||||
return new AnnounceViewHolder(view);
|
||||
return new ItemViewHolder(view);
|
||||
case TYPE_SHOW_MORE:
|
||||
view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.list_all_show_more, parent, false);
|
||||
return new CustomViewHolder(view);
|
||||
default:
|
||||
//noinspection ConstantConditions
|
||||
return null;
|
||||
@@ -62,39 +67,61 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
||||
// Just as an example, return 0 or 2 depending on position
|
||||
// Note that unlike in ListView adapters, types don't have to be contiguous
|
||||
if (position < 3)
|
||||
return position % 2;
|
||||
else
|
||||
return 2;
|
||||
return position % 2; // HEADER, DESCRIPTION, HEADER
|
||||
int count = 2;
|
||||
|
||||
// Announcements
|
||||
if (position <= count+getAnnounceCount(2))
|
||||
return TYPE_ITEM;
|
||||
count += getAnnounceCount(3);
|
||||
if (position <= count)
|
||||
return TYPE_SHOW_MORE;
|
||||
|
||||
// Assignments
|
||||
count++;
|
||||
if (position <= count)
|
||||
return TYPE_HEADER;
|
||||
count++;
|
||||
if (position <= count+getAssignmentCount(2))
|
||||
return TYPE_ITEM;
|
||||
count += getAssignmentCount(3);
|
||||
if (position <= count)
|
||||
return TYPE_SHOW_MORE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
||||
if (mValue == null)
|
||||
return;
|
||||
int announce_count = getAnnounceCount(2);
|
||||
if (position == 0) {
|
||||
HeaderViewHolder h = (HeaderViewHolder) holder;
|
||||
h.mCaption.setText(h.mView.getResources().getText(R.string.description));
|
||||
h.mCaption.setText(R.string.description);
|
||||
} else if (position == 1) {
|
||||
DescriptionViewHolder d = (DescriptionViewHolder) holder;
|
||||
d.mText.setText(mValue.description);
|
||||
//d.mText.setText(d.mView.getResources().getText(R.string.app_name));
|
||||
} else if (position == 2) {
|
||||
HeaderViewHolder h = (HeaderViewHolder) holder;
|
||||
h.mCaption.setText(h.mView.getResources().getString(R.string.announcements_count, getAnnounceCount()));
|
||||
} else if (position <= announce_count+2) {
|
||||
AnnounceViewHolder a = (AnnounceViewHolder) holder;
|
||||
} else if (position <= getAnnounceCount(2)+2) {
|
||||
ItemViewHolder a = (ItemViewHolder) holder;
|
||||
Announcement announce = mValue.announcements.get(position - 3);
|
||||
a.mTitle.setText(announce.getTitle());
|
||||
a.mPublisher.setText(announce.getCreatedBy());
|
||||
a.mDate.setText(Conversion.getModifiedDate(announce.getCreatedOn()));
|
||||
a.mSubLeft.setText(announce.getCreatedBy());
|
||||
a.mSubRight.setText(Conversion.getModifiedDate(announce.getCreatedOn()));
|
||||
} else if (position <= getAnnounceCount(3)+getAssignmentCount(2)+3) {
|
||||
ItemViewHolder a = (ItemViewHolder) holder;
|
||||
Assignment assignment = mValue.assignments.get(position - 3);
|
||||
a.mTitle.setText(assignment.getTitle());
|
||||
a.mSubLeft.setText(assignment.getStatus());
|
||||
a.mSubRight.setText(Conversion.getModifiedDate(assignment.getDueDate()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
if (mValue != null) {
|
||||
return 3+getAnnounceCount();
|
||||
return 4+getAnnounceCount(3)+getAssignmentCount(3);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -109,6 +136,16 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
||||
return Math.min(max, getAnnounceCount());
|
||||
}
|
||||
|
||||
private int getAssignmentCount() {
|
||||
if (mValue.assignments != null)
|
||||
return mValue.assignments.size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int getAssignmentCount(int max) {
|
||||
return Math.min(max, getAssignmentCount());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -131,11 +168,11 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
||||
}
|
||||
|
||||
public class DescriptionViewHolder extends CustomViewHolder {
|
||||
final TextView mText;
|
||||
final ExpandableTextView mText;
|
||||
|
||||
DescriptionViewHolder(View view) {
|
||||
super(view);
|
||||
mText = view.findViewById(R.id.description);
|
||||
mText = view.findViewById(R.id.expand_text_view);//.findViewById(R.id.description);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -145,21 +182,21 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
||||
}
|
||||
|
||||
|
||||
public class AnnounceViewHolder extends CustomViewHolder {
|
||||
public class ItemViewHolder extends CustomViewHolder {
|
||||
final TextView mTitle;
|
||||
final TextView mPublisher;
|
||||
final TextView mDate;
|
||||
final TextView mSubLeft;
|
||||
final TextView mSubRight;
|
||||
|
||||
AnnounceViewHolder(View view) {
|
||||
ItemViewHolder(View view) {
|
||||
super(view);
|
||||
mTitle = view.findViewById(R.id.title);
|
||||
mPublisher = view.findViewById(R.id.publisher);
|
||||
mDate = view.findViewById(R.id.date);
|
||||
mSubLeft = view.findViewById(R.id.sub_left);
|
||||
mSubRight = view.findViewById(R.id.sub_right);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return super.toString() + " '" + mTitle.getText() + "' '" + mPublisher.getText() + "' '" + mDate.getText() + "'";
|
||||
return super.toString() + " '" + mTitle.getText() + "' '" + mSubLeft.getText() + "' '" + mSubRight.getText() + "'";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,20 +7,15 @@ import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import de.sebse.fuplanner.MainActivity;
|
||||
import de.sebse.fuplanner.R;
|
||||
import de.sebse.fuplanner.fragments.ModulesRecyclerViewAdapter;
|
||||
import de.sebse.fuplanner.services.KVV.KVV;
|
||||
import de.sebse.fuplanner.services.KVV.Modules;
|
||||
import de.sebse.fuplanner.tools.logging.Logger;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
@@ -31,6 +26,7 @@ public class ModDetailOverviewFragment 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";
|
||||
private static Logger slog = new Logger(ModDetailOverviewFragment.class);
|
||||
|
||||
// TODO: Rename and change types of parameters
|
||||
private int mItemPos;
|
||||
@@ -54,8 +50,7 @@ public class ModDetailOverviewFragment extends Fragment {
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_POSITION, itemPosition);
|
||||
fragment.setArguments(args);
|
||||
String s = "ModDetailOverviewFragment".toString();
|
||||
Log.d(s, "new Instance");
|
||||
slog.d("new Instance");
|
||||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,5 +5,5 @@ package de.sebse.fuplanner.services.GoogleAuth;
|
||||
*/
|
||||
|
||||
public interface ConnectedListener {
|
||||
public void connected();
|
||||
void connected();
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ package de.sebse.fuplanner.services.GoogleAuth;
|
||||
*/
|
||||
|
||||
public interface CredentialsListener {
|
||||
public void onCredentials(Credentials credentials);
|
||||
void onCredentials(Credentials credentials);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.sebse.fuplanner.services.GoogleAuth;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.IntentSender;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.util.Log;
|
||||
@@ -10,7 +9,6 @@ import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.auth.api.credentials.Credential;
|
||||
import com.google.android.gms.auth.api.credentials.CredentialRequest;
|
||||
import com.google.android.gms.auth.api.credentials.CredentialRequestResponse;
|
||||
import com.google.android.gms.auth.api.credentials.CredentialsClient;
|
||||
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
@@ -18,8 +16,6 @@ import com.google.android.gms.common.GoogleApiAvailability;
|
||||
import com.google.android.gms.common.api.ApiException;
|
||||
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||
import com.google.android.gms.common.api.ResolvableApiException;
|
||||
import com.google.android.gms.tasks.OnCompleteListener;
|
||||
import com.google.android.gms.tasks.Task;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
@@ -65,9 +61,7 @@ public class GoogleAuth {
|
||||
.build();
|
||||
|
||||
|
||||
mCredentialsClient.request(request).addOnCompleteListener(new OnCompleteListener<CredentialRequestResponse>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
|
||||
mCredentialsClient.request(request).addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
// Successfully read the credential without any user interaction, this
|
||||
// means there was only a single credential and the user has auto
|
||||
@@ -98,7 +92,6 @@ public class GoogleAuth {
|
||||
Log.w(TAG, "Unexpected status code: " + ae.getStatusCode());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -111,9 +104,7 @@ public class GoogleAuth {
|
||||
Credential credential = new Credential.Builder(username)
|
||||
.setPassword(password)
|
||||
.build();
|
||||
mCredentialsClient.save(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<Void> task) {
|
||||
mCredentialsClient.save(credential).addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
showToast("Credential saved.");
|
||||
return;
|
||||
@@ -130,7 +121,6 @@ public class GoogleAuth {
|
||||
Log.w(TAG, "Save failed.", e);
|
||||
showToast("Credential Save Failed");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -142,13 +132,10 @@ public class GoogleAuth {
|
||||
Credential credential = new Credential.Builder(username)
|
||||
.setPassword(password)
|
||||
.build();
|
||||
mCredentialsClient.delete(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
|
||||
@Override
|
||||
public void onComplete(@NonNull Task<Void> task) {
|
||||
mCredentialsClient.delete(credential).addOnCompleteListener(task -> {
|
||||
if (task.isSuccessful()) {
|
||||
// Credential was deleted successfully
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
package de.sebse.fuplanner.services.KVV;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.volley.Response;
|
||||
import com.android.volley.VolleyError;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -15,7 +11,6 @@ import de.sebse.fuplanner.tools.network.HTTPService;
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
import de.sebse.fuplanner.tools.network.Result;
|
||||
|
||||
/**
|
||||
* Created by sebastian on 24.10.17.
|
||||
@@ -53,9 +48,7 @@ class KVVLogin extends HTTPService {
|
||||
-> JSESSIONID 5c10406f-588c-4c16-96e9-c80d115417de.tomcat1
|
||||
*/
|
||||
private void startKVVSession(final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||
get("https://kvv.imp.fu-berlin.de/portal/login", null, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
get("https://kvv.imp.fu-berlin.de/portal/login", null, response -> {
|
||||
String cookies = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies==null) {
|
||||
errorCallback.onError(new NetworkError(100101, -1, "Error on starting KVV session!"));
|
||||
@@ -69,13 +62,7 @@ class KVVLogin extends HTTPService {
|
||||
return;
|
||||
}
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100100, error.networkResponse.statusCode, "Error on starting KVV session!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100100, error.networkResponse.statusCode, "Error on starting KVV session!")));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -88,9 +75,7 @@ class KVVLogin extends HTTPService {
|
||||
private void getSAMLRequest(String JSESSIONID, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||
HashMap<String, String> cookies = new HashMap<>();
|
||||
cookies.put("JSESSIONID", JSESSIONID);
|
||||
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", cookies, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", cookies, response -> {
|
||||
String location = response.getHeaders().get("Location");
|
||||
if (location==null) {
|
||||
errorCallback.onError(new NetworkError(100111, -1, "Error on getting SAML request!"));
|
||||
@@ -99,13 +84,7 @@ class KVVLogin extends HTTPService {
|
||||
HashMap<String, String> object = new HashMap<>();
|
||||
object.put("Location", location);
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100110, error.networkResponse.statusCode, "Error on getting SAML request!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100110, error.networkResponse.statusCode, "Error on getting SAML request!")));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,9 +96,7 @@ class KVVLogin extends HTTPService {
|
||||
-> ROUTEID .1
|
||||
*/
|
||||
private void startIdentSession(String url, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||
get(url, null, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
get(url, null, response -> {
|
||||
String cookies = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies==null) {
|
||||
errorCallback.onError(new NetworkError(100121, -1, "Error on starting Ident session!"));
|
||||
@@ -133,13 +110,7 @@ class KVVLogin extends HTTPService {
|
||||
return;
|
||||
}
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100120, error.networkResponse.statusCode, "Error on starting Ident session!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100120, error.networkResponse.statusCode, "Error on starting Ident session!")));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -160,34 +131,26 @@ class KVVLogin extends HTTPService {
|
||||
HashMap<String, String> body = new HashMap<>();
|
||||
body.put("j_username", username);
|
||||
body.put("j_password", password);
|
||||
post("https://identity.fu-berlin.de/idp-fub/Authn/UserPassword", cookies, body, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
post("https://identity.fu-berlin.de/idp-fub/Authn/UserPassword", cookies, body, response -> {
|
||||
if (first) {
|
||||
callback.onResponse(new HashMap<String, String>());
|
||||
callback.onResponse(new HashMap<>());
|
||||
return;
|
||||
}
|
||||
|
||||
String cookies = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies==null) {
|
||||
String cookies1 = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies1 ==null) {
|
||||
errorCallback.onError(new NetworkError(100131, -1, "Error on logging in to Identity Server!"));
|
||||
return;
|
||||
}
|
||||
HashMap<String, String> object;
|
||||
try {
|
||||
object = getCookie(cookies, new String[]{"_idp_session"});
|
||||
object = getCookie(cookies1, new String[]{"_idp_session"});
|
||||
} catch (NoSuchFieldException e) {
|
||||
errorCallback.onError(new NetworkError(100132, -1, "Error on logging in to Identity Server!"));
|
||||
return;
|
||||
}
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100130, error.networkResponse.statusCode, "Error on logging in to Identity Server!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100130, error.networkResponse.statusCode, "Error on logging in to Identity Server!")));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -205,9 +168,7 @@ class KVVLogin extends HTTPService {
|
||||
cookies.put("_idp_authn_lc_key", _idp_authn_lc_key);
|
||||
cookies.put("ROUTEID", ROUTEID);
|
||||
cookies.put("_idp_session", _idp_session);
|
||||
get("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO", cookies, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
get("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO", cookies, response -> {
|
||||
HashMap<String, String> object = new HashMap<>();
|
||||
|
||||
Pattern pattern = Pattern.compile("ss:mem:([0-9a-f]+)");
|
||||
@@ -227,13 +188,7 @@ class KVVLogin extends HTTPService {
|
||||
object.put("SAMLResponse", matcher.group(1));
|
||||
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100140, error.networkResponse.statusCode, "Error on getting SAML response!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100140, error.networkResponse.statusCode, "Error on getting SAML response!")));
|
||||
}
|
||||
|
||||
|
||||
@@ -251,11 +206,9 @@ class KVVLogin extends HTTPService {
|
||||
HashMap<String, String> body = new HashMap<>();
|
||||
body.put("RelayState", RelayState);
|
||||
body.put("SAMLResponse", SAMLResponse);
|
||||
post("https://kvv.imp.fu-berlin.de/Shibboleth.sso/SAML2/POST", cookies, body, new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
String cookies = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies==null) {
|
||||
post("https://kvv.imp.fu-berlin.de/Shibboleth.sso/SAML2/POST", cookies, body, response -> {
|
||||
String cookies1 = response.getHeaders().get("Set-Cookie");
|
||||
if (cookies1 ==null) {
|
||||
errorCallback.onError(new NetworkError(100151, -1, "Error on starting KVV session!"));
|
||||
return;
|
||||
}
|
||||
@@ -263,7 +216,7 @@ class KVVLogin extends HTTPService {
|
||||
|
||||
|
||||
Pattern pattern = Pattern.compile("(_shibsession_[0-9a-f]+)=([^;]+);");
|
||||
Matcher matcher = pattern.matcher(cookies);
|
||||
Matcher matcher = pattern.matcher(cookies1);
|
||||
if (!matcher.find()) {
|
||||
errorCallback.onError(new NetworkError(100152, -1, "Error on starting Ident session!"));
|
||||
}
|
||||
@@ -271,13 +224,7 @@ class KVVLogin extends HTTPService {
|
||||
object.put("shibsessionName", matcher.group(2));
|
||||
|
||||
callback.onResponse(object);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100150, error.networkResponse.statusCode, "Error on starting Ident session!"));
|
||||
}
|
||||
});
|
||||
}, error -> errorCallback.onError(new NetworkError(100150, error.networkResponse.statusCode, "Error on starting Ident session!")));
|
||||
}
|
||||
|
||||
|
||||
@@ -288,17 +235,7 @@ class KVVLogin extends HTTPService {
|
||||
_b1912c5a03d733a80bd3fee772bf68d4
|
||||
*/
|
||||
private void finishKVVlogin(LoginToken loginToken, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", loginToken.getCookies(), new Response.Listener<Result>() {
|
||||
@Override
|
||||
public void onResponse(Result response) {
|
||||
callback.onResponse(new HashMap<String, String>());
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
errorCallback.onError(new NetworkError(100160, error.networkResponse.statusCode, "Cannot finish login process!"));
|
||||
}
|
||||
});
|
||||
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", loginToken.getCookies(), response -> callback.onResponse(new HashMap<>()), error -> errorCallback.onError(new NetworkError(100160, error.networkResponse.statusCode, "Cannot finish login process!")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public class KVVModuleList extends HTTPService {
|
||||
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 retreived!"));
|
||||
errorCallback.onError(new NetworkError(101101, 403, "No module list retrieved!"));
|
||||
return;
|
||||
}
|
||||
Modules modules = new Modules();
|
||||
@@ -78,11 +78,14 @@ public class KVVModuleList extends HTTPService {
|
||||
}
|
||||
|
||||
public void getModule(int index, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
||||
this.getModuleList(success -> {
|
||||
callback.onResponse(success.get(index));
|
||||
}, errorCallback);
|
||||
this.getModuleList(success -> callback.onResponse(success.get(index)), errorCallback);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void getAnnouncements(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
||||
queueModuleDetails.add(module.getID(), () -> {
|
||||
if (module.announcements != null) {
|
||||
@@ -103,7 +106,7 @@ public class KVVModuleList extends HTTPService {
|
||||
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) {
|
||||
errorCallback.onError(new NetworkError(101201, 403, "No announcements retreived!"));
|
||||
errorCallback.onError(new NetworkError(101201, 403, "No announcements retrieved!"));
|
||||
return;
|
||||
}
|
||||
ArrayList<Announcement> announcements = new ArrayList<>();
|
||||
@@ -129,4 +132,28 @@ public class KVVModuleList extends HTTPService {
|
||||
callback.onResponse(announcements);
|
||||
}, error -> errorCallback.onError(new NetworkError(101203, error.networkResponse.statusCode, "Cannot get announcements!")));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public void getAssignments(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
||||
queueModuleDetails.add(module.getID(), () -> {
|
||||
if (module.assignments != null) {
|
||||
callback.onResponse(module);
|
||||
queueModuleDetails.next(module.getID());
|
||||
return;
|
||||
}
|
||||
getAssignmentsUpgrade(module.getID(), success -> {
|
||||
module.assignments = success;
|
||||
callback.onResponse(module);
|
||||
queueModuleDetails.next(module.getID());
|
||||
}, errorCallback);
|
||||
});
|
||||
}
|
||||
|
||||
private void getAssignmentsUpgrade(String ID, final NetworkCallback<ArrayList<Assignment>> callback, final NetworkErrorCallback errorCallback) {
|
||||
callback.onResponse(new ArrayList<Assignment>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,13 +160,13 @@ public class Modules /*extends EventEmitter<Triplet<Integer, Modules.UpgradeModu
|
||||
int size = list.size();
|
||||
do {
|
||||
next++;
|
||||
} while (next < size && !accept(list.get(next)));
|
||||
} while (next < size && decline(list.get(next)));
|
||||
if (next == size)
|
||||
next = -1;
|
||||
}
|
||||
|
||||
private boolean accept(Module ob){
|
||||
return ob.semester.equals(latestSemester);
|
||||
private boolean decline(Module ob){
|
||||
return !ob.semester.equals(latestSemester);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -188,6 +188,7 @@ public class Modules /*extends EventEmitter<Triplet<Integer, Modules.UpgradeModu
|
||||
public final String description;
|
||||
private final String ID;
|
||||
public ArrayList<Announcement> announcements;
|
||||
public ArrayList<Assignment> assignments;
|
||||
|
||||
/*private Module() {
|
||||
this(null, null, null, null, null);
|
||||
|
||||
@@ -6,8 +6,6 @@ import android.util.Log;
|
||||
import com.android.volley.AuthFailureError;
|
||||
import com.android.volley.Request;
|
||||
import com.android.volley.RequestQueue;
|
||||
import com.android.volley.Response;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.VolleyLog;
|
||||
import com.android.volley.toolbox.StringRequest;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
@@ -35,17 +33,7 @@ public class MensaPlan {
|
||||
post.put("date", "2017-10-13");
|
||||
final String requestBody = post.toString();
|
||||
|
||||
StringRequest request = new StringRequest(Request.Method.POST, "https://www.stw.berlin/xhr/speiseplan-wochentag.html", new Response.Listener<String>() {
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
Log.d("MensaPlan DDDD", response);
|
||||
}
|
||||
}, new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
Log.d("MensaPlan EEEE", error.getMessage());
|
||||
}
|
||||
}) {
|
||||
StringRequest request = new StringRequest(Request.Method.POST, "https://www.stw.berlin/xhr/speiseplan-wochentag.html", response -> Log.d("MensaPlan DDDD", response), error -> Log.d("MensaPlan EEEE", error.getMessage())) {
|
||||
@Override
|
||||
public String getBodyContentType() {
|
||||
return "application/json; charset=utf-8";
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package de.sebse.fuplanner.tools;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||
|
||||
public class AsyncQueue {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.sebse.fuplanner.tools;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TargetApi;
|
||||
import android.os.Build;
|
||||
import android.text.format.DateFormat;
|
||||
@@ -16,13 +17,14 @@ public class Conversion {
|
||||
return getModifiedDate(Locale.getDefault(), modified);
|
||||
}
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
public static String getModifiedDate(Locale locale, long modified) {
|
||||
SimpleDateFormat dateFormat = null;
|
||||
SimpleDateFormat dateFormat;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||
dateFormat = new SimpleDateFormat(getDateFormat(locale));
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat("MMM/dd/yyyy hh:mm:ss aa");
|
||||
dateFormat = new SimpleDateFormat("MMM/dd/yyyy hh:mm:ss aa", locale);
|
||||
}
|
||||
|
||||
return dateFormat.format(new Date(modified));
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package de.sebse.fuplanner.tools;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.intellij.lang.annotations.Language;
|
||||
|
||||
import java.util.Iterator;
|
||||
@@ -26,10 +24,7 @@ public class Regex {
|
||||
|
||||
public static Iterable<MatchResult> allMatches(@Language("Regexp") String regex, final CharSequence input) {
|
||||
final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
|
||||
return new Iterable<MatchResult>() {
|
||||
@NonNull
|
||||
public Iterator<MatchResult> iterator() {
|
||||
return new Iterator<MatchResult>() {
|
||||
return () -> new Iterator<MatchResult>() {
|
||||
// Use a matcher internally.
|
||||
final Matcher matcher = pattern.matcher(input);
|
||||
// Keep a match around that supports any interleaving of hasNext/next calls.
|
||||
@@ -58,6 +53,4 @@ public class Regex {
|
||||
public void remove() { throw new UnsupportedOperationException(); }
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,8 @@ public class BetterHurlStack extends HurlStack {
|
||||
|
||||
private final UrlRewriter mUrlRewriter;
|
||||
private final SSLSocketFactory mSslSocketFactory;
|
||||
private boolean followRedirects;
|
||||
@SuppressWarnings({"unused", "FieldCanBeLocal"})
|
||||
private boolean followRedirects; // TODO auto-redirect
|
||||
|
||||
BetterHurlStack() {
|
||||
this(true);
|
||||
@@ -130,7 +131,7 @@ public class BetterHurlStack extends HurlStack {
|
||||
|
||||
/**
|
||||
* Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}.
|
||||
* @param connection
|
||||
* @param connection A http connection
|
||||
* @return an HttpEntity populated with data from <code>connection</code>.
|
||||
*/
|
||||
private static HttpEntity entityFromConnection(HttpURLConnection connection) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package de.sebse.fuplanner.tools.network;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.volley.AuthFailureError;
|
||||
import com.android.volley.NetworkResponse;
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:contentDescription="@string/cd_ic_launcher"/>
|
||||
|
||||
<!-- Email Label -->
|
||||
<android.support.design.widget.TextInputLayout
|
||||
@@ -29,7 +30,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textEmailAddress"
|
||||
android:hint="Username" />
|
||||
android:hint="@string/username" />
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<!-- Password Label -->
|
||||
@@ -42,7 +43,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="textPassword"
|
||||
android:hint="Password"/>
|
||||
android:hint="@string/password"/>
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.v7.widget.AppCompatButton
|
||||
@@ -52,7 +53,7 @@
|
||||
android:layout_marginTop="24dp"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:padding="12dp"
|
||||
android:text="Login"/>
|
||||
android:text="@string/log_in"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
@@ -9,6 +9,6 @@
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:text="Announcement fragment" />
|
||||
android:text="@string/lorem_ipsum_100" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -10,6 +10,7 @@
|
||||
android:layout_width="@android:dimen/thumbnail_width"
|
||||
android:layout_height="@android:dimen/thumbnail_height"
|
||||
android:layout_gravity="center"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:src="@mipmap/ic_launcher"
|
||||
android:contentDescription="@string/cd_ic_launcher"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/caption"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="Caption"
|
||||
tools:text="Caption"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||
</LinearLayout>
|
||||
|
||||
19
app/src/main/res/layout/list_all_show_more.xml
Normal file
19
app/src/main/res/layout/list_all_show_more.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?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="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/caption"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/show_all"
|
||||
android:textStyle="bold"
|
||||
android:typeface="sans"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/colorFUSecondary"
|
||||
/>
|
||||
</LinearLayout>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="5dip" >
|
||||
@@ -15,21 +15,21 @@
|
||||
tools:text="Test this new stuff!" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/publisher"
|
||||
android:id="@+id/sub_left"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/title"
|
||||
android:layout_marginTop="5dip"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
tools:text="Peter Müller" />
|
||||
tools:text="Peter Bauer" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/date"
|
||||
android:id="@+id/sub_right"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBaseline="@+id/publisher"
|
||||
android:layout_alignBottom="@+id/publisher"
|
||||
android:layout_alignBaseline="@id/sub_left"
|
||||
android:layout_alignBottom="@id/sub_left"
|
||||
android:textColor="#343434"
|
||||
android:textSize="12sp"
|
||||
android:layout_alignParentEnd="true"
|
||||
|
||||
@@ -1,14 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!-- sample xml -->
|
||||
<com.ms.square.android.expandabletextview.ExpandableTextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:expandableTextView="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/expand_text_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
expandableTextView:maxCollapsedLines="4"
|
||||
expandableTextView:animDuration="200">
|
||||
<TextView
|
||||
android:id="@id/expandable_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:textSize="16sp"
|
||||
android:textColor="#666666" />
|
||||
<ImageButton
|
||||
android:id="@id/expand_collapse"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"
|
||||
android:layout_gravity="end|bottom"
|
||||
android:background="@android:color/transparent"
|
||||
android:contentDescription="@string/description" />
|
||||
</com.ms.square.android.expandabletextview.ExpandableTextView>
|
||||
|
||||
<!--<TextView
|
||||
android:id="@+id/description"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/text_margin"
|
||||
android:text="@string/lorem_ipsum_100"
|
||||
android:textAppearance="?attr/textAppearanceListItem" />
|
||||
android:textAppearance="?attr/textAppearanceListItem" />-->
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/nav_header_height"
|
||||
android:background="@drawable/side_nav_bar"
|
||||
@@ -17,7 +18,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Widget.AppCompat.Button.Colored"
|
||||
android:text="Login"
|
||||
android:text="@string/log_in"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
@@ -27,14 +28,15 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@mipmap/ic_launcher"
|
||||
android:visibility="gone" />
|
||||
android:visibility="gone"
|
||||
android:contentDescription="@string/cd_ic_launcher"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/login_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:text="Android Studio"
|
||||
tools:text="Android Studio"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:visibility="gone" />
|
||||
</LinearLayout>
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/nav_header_height"
|
||||
android:background="@drawable/side_nav_bar"
|
||||
android:gravity="bottom"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:srcCompat="@mipmap/ic_launcher" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/login_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||
android:text="Android Studio"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -5,15 +5,15 @@
|
||||
<item
|
||||
android:id="@+id/nav_dining"
|
||||
android:icon="@drawable/ic_local_dining"
|
||||
android:title="Mensaplan" />
|
||||
android:title="@string/canteen_plan" />
|
||||
</group>
|
||||
|
||||
<item android:title="Optionen">
|
||||
<item android:title="@string/options">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/nav_share"
|
||||
android:icon="@drawable/ic_menu_share"
|
||||
android:title="Teilen"/>
|
||||
android:title="@string/share"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
|
||||
@@ -5,37 +5,37 @@
|
||||
<item
|
||||
android:id="@+id/nav_schedule"
|
||||
android:icon="@drawable/ic_event"
|
||||
android:title="Stundenplan"
|
||||
android:title="@string/schedule"
|
||||
android:orderInCategory="10"/>
|
||||
<item
|
||||
android:id="@+id/nav_modules"
|
||||
android:icon="@drawable/ic_apps"
|
||||
android:title="Module"
|
||||
android:title="@string/events"
|
||||
android:orderInCategory="100" />
|
||||
<item
|
||||
android:id="@+id/nav_dining"
|
||||
android:icon="@drawable/ic_local_dining"
|
||||
android:title="Mensaplan"
|
||||
android:title="@string/canteen_plan"
|
||||
android:orderInCategory="200"/>
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_settings"
|
||||
android:title="Einstellungen"
|
||||
android:title="@string/settings"
|
||||
android:orderInCategory="300"/>
|
||||
</group>
|
||||
|
||||
<item android:title="Optionen"
|
||||
<item android:title="@string/options"
|
||||
android:orderInCategory="499">
|
||||
<menu>
|
||||
<item
|
||||
android:id="@+id/nav_logout"
|
||||
android:icon="@drawable/ic_exit_to_app"
|
||||
android:title="Logout"
|
||||
android:title="@string/log_out"
|
||||
android:orderInCategory="500"/>
|
||||
<item
|
||||
android:id="@+id/nav_share"
|
||||
android:icon="@drawable/ic_menu_share"
|
||||
android:title="Teilen"
|
||||
android:title="@string/share"
|
||||
android:orderInCategory="600"/>
|
||||
</menu>
|
||||
</item>
|
||||
|
||||
@@ -7,10 +7,21 @@
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
<!-- TODO: Remove or change this placeholder text -->
|
||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||
<string name="overview">Overview</string>
|
||||
<string name="announcements">Announcements</string>
|
||||
<string name="lorem_ipsum_100">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.</string>
|
||||
<string name="description">Description</string>
|
||||
<string name="announcements_count">Announcements (%1$d)</string>
|
||||
<string name="cd_ic_launcher">App Icon</string>
|
||||
<string name="schedule">Schedule</string>
|
||||
<string name="events">Events</string>
|
||||
<string name="canteen_plan">Canteen Plan</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="options">Options</string>
|
||||
<string name="log_out">Log out</string>
|
||||
<string name="share">Share</string>
|
||||
<string name="log_in">Log in</string>
|
||||
<string name="username">Username</string>
|
||||
<string name="password">Password</string>
|
||||
<string name="show_all">Show All</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user