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:appcompat-v7:27.1.1'
|
||||||
implementation 'com.android.support:design: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'
|
implementation 'com.android.volley:volley:1.0.0'
|
||||||
//noinspection GradleDependency
|
//noinspection GradleDependency
|
||||||
implementation 'com.google.android.gms:play-services-auth:15.0.0'
|
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 '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 'com.android.support:support-v4:27.1.1'
|
||||||
implementation 'org.jetbrains:annotations-java5:15.0'
|
implementation 'org.jetbrains:annotations-java5:15.0'
|
||||||
|
implementation 'com.ms-square:expandableTextView:0.1.4'
|
||||||
implementation files('libs/jericho-html-3.4.jar')
|
implementation files('libs/jericho-html-3.4.jar')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.VIEW" />
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|||||||
@@ -22,17 +22,11 @@ import de.sebse.fuplanner.fragments.LoginFragment;
|
|||||||
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
import de.sebse.fuplanner.fragments.moddetails.ModDetailFragment;
|
||||||
import de.sebse.fuplanner.fragments.ModulesFragment;
|
import de.sebse.fuplanner.fragments.ModulesFragment;
|
||||||
import de.sebse.fuplanner.fragments.StartupFragment;
|
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.Credentials;
|
||||||
import de.sebse.fuplanner.services.GoogleAuth.CredentialsListener;
|
|
||||||
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
||||||
import de.sebse.fuplanner.services.KVV.KVV;
|
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.services.KVV.Modules;
|
||||||
import de.sebse.fuplanner.tools.logging.Logger;
|
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
|
public class MainActivity extends AppCompatActivity
|
||||||
implements NavigationView.OnNavigationItemSelectedListener,
|
implements NavigationView.OnNavigationItemSelectedListener,
|
||||||
@@ -55,7 +49,7 @@ public class MainActivity extends AppCompatActivity
|
|||||||
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
DrawerLayout drawer = findViewById(R.id.drawer_layout);
|
||||||
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
|
||||||
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
|
||||||
drawer.setDrawerListener(toggle);
|
drawer.addDrawerListener(toggle);
|
||||||
toggle.syncState();
|
toggle.syncState();
|
||||||
|
|
||||||
NavigationView navigationView = findViewById(R.id.nav_view);
|
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);
|
findViewById(R.id.app_bar_layout).setVisibility(View.GONE);
|
||||||
|
|
||||||
|
|
||||||
this.getGoogleAuth().connect(new ConnectedListener() {
|
this.getGoogleAuth().connect(() -> {
|
||||||
@Override
|
// getGoogleAuth().setLoginState("seedorf96", "m&gcwBaT@");
|
||||||
public void connected() {
|
getGoogleAuth().getLoginState(credentials -> {
|
||||||
// getGoogleAuth().setLoginState("seedorf96", "m&gcwBaT@");
|
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
|
||||||
getGoogleAuth().getLoginState(new CredentialsListener() {
|
MainActivity.this.getKVV().endUpdate();
|
||||||
@Override
|
changeLoginState(null);
|
||||||
public void onCredentials(final Credentials credentials) {
|
return;
|
||||||
if (credentials == null || credentials.getUsername() == null || credentials.getPassword() == null) {
|
}
|
||||||
MainActivity.this.getKVV().endUpdate();
|
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), success -> {
|
||||||
changeLoginState(null);
|
MainActivity.this.getKVV().endUpdate();
|
||||||
return;
|
changeLoginState(credentials);
|
||||||
}
|
}, error -> {
|
||||||
MainActivity.this.getKVV().login(credentials.getUsername(), credentials.getPassword(), new NetworkCallback<LoginToken>() {
|
log.e(error);
|
||||||
@Override
|
MainActivity.this.getKVV().endUpdate();
|
||||||
public void onResponse(@NonNull LoginToken success) {
|
changeLoginState(null);
|
||||||
MainActivity.this.getKVV().endUpdate();
|
|
||||||
changeLoginState(credentials);
|
|
||||||
}
|
|
||||||
}, new NetworkErrorCallback() {
|
|
||||||
@Override
|
|
||||||
public void onError(NetworkError error) {
|
|
||||||
log.e(error);
|
|
||||||
MainActivity.this.getKVV().endUpdate();
|
|
||||||
changeLoginState(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,14 +141,11 @@ public class MainActivity extends AppCompatActivity
|
|||||||
break;
|
break;
|
||||||
case R.id.nav_logout:
|
case R.id.nav_logout:
|
||||||
this.getKVV().logout();
|
this.getKVV().logout();
|
||||||
this.getGoogleAuth().getLoginState(new CredentialsListener() {
|
this.getGoogleAuth().getLoginState(credentials -> {
|
||||||
@Override
|
if (credentials != null) {
|
||||||
public void onCredentials(Credentials credentials) {
|
MainActivity.this.getGoogleAuth().deleteLoginState(credentials.getUsername(), credentials.getPassword());
|
||||||
if (credentials != null) {
|
|
||||||
MainActivity.this.getGoogleAuth().deleteLoginState(credentials.getUsername(), credentials.getPassword());
|
|
||||||
}
|
|
||||||
MainActivity.this.changeLoginState(null);
|
|
||||||
}
|
}
|
||||||
|
MainActivity.this.changeLoginState(null);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -236,29 +215,21 @@ public class MainActivity extends AppCompatActivity
|
|||||||
navigationView.getMenu().clear();
|
navigationView.getMenu().clear();
|
||||||
navigationView.inflateMenu(R.menu.activity_main_drawer_login);
|
navigationView.inflateMenu(R.menu.activity_main_drawer_login);
|
||||||
navigationView.setCheckedItem(R.id.nav_modules);
|
navigationView.setCheckedItem(R.id.nav_modules);
|
||||||
getKVV().getModuleList(new NetworkCallback<Modules>() {
|
getKVV().getModuleList(success -> {
|
||||||
@Override
|
log.d("Modules.get", success.size());
|
||||||
public void onResponse(@NonNull Modules success) {
|
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
|
||||||
log.d("Modules.get", success.size());
|
int i = 0;
|
||||||
//SubMenu moduleMenu = navigationView.getMenu().findItem(R.id.nav_modules).getSubMenu();
|
for (Iterator<Modules.Module> it = success.latestSemesterIterator(); it.hasNext(); ) {
|
||||||
int i = 0;
|
Modules.Module module = it.next();
|
||||||
for (Iterator<Modules.Module> it = success.latestSemesterIterator(); it.hasNext(); ) {
|
MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
|
||||||
Modules.Module module = it.next();
|
final int finalI = i;
|
||||||
MenuItem menuItem = navigationView.getMenu().add(Menu.NONE, Menu.NONE, 101 + i, module.title);
|
menuItem.setOnMenuItemClickListener(item -> {
|
||||||
final int finalI = i;
|
onModulesFragmentInteraction(finalI);
|
||||||
menuItem.setOnMenuItemClickListener(item -> {
|
return false;
|
||||||
onModulesFragmentInteraction(finalI);
|
});
|
||||||
return false;
|
i++;
|
||||||
});
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}, new NetworkErrorCallback() {
|
}, error -> log.d("Modules.error", error));
|
||||||
@Override
|
|
||||||
public void onError(NetworkError error) {
|
|
||||||
log.d("Modules.error", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,16 +251,8 @@ public class MainActivity extends AppCompatActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onModulesFragmentInteraction(final int itemPosition) {
|
public void onModulesFragmentInteraction(final int itemPosition) {
|
||||||
log.d("Item clicked", itemPosition);
|
log.d("Item clicked", itemPosition);
|
||||||
getKVV().getModuleList(new NetworkCallback<Modules>() {
|
getKVV().getModuleList(success -> log.d(success.get(itemPosition).title), error -> {
|
||||||
@Override
|
// TODO
|
||||||
public void onResponse(@NonNull Modules success) {
|
|
||||||
log.d(success.get(itemPosition).title);
|
|
||||||
}
|
|
||||||
}, new NetworkErrorCallback() {
|
|
||||||
@Override
|
|
||||||
public void onError(NetworkError error) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import android.content.Context;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
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.Credentials;
|
||||||
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
import de.sebse.fuplanner.services.GoogleAuth.GoogleAuth;
|
||||||
import de.sebse.fuplanner.services.KVV.KVV;
|
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.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.
|
* A simple {@link Fragment} subclass.
|
||||||
@@ -63,54 +58,45 @@ public class LoginFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
|
|
||||||
View v = inflater.inflate(R.layout.fragment_login, container, false);
|
View v = inflater.inflate(R.layout.fragment_login, container, false);
|
||||||
View btn_login = v.findViewById(R.id.btn_login);
|
View btn_login = v.findViewById(R.id.btn_login);
|
||||||
if (btn_login != null) {
|
if (btn_login != null) {
|
||||||
btn_login.setOnClickListener(new View.OnClickListener() {
|
btn_login.setOnClickListener(view -> {
|
||||||
@Override
|
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
|
||||||
public void onClick(View view) {
|
R.style.FUTheme_Dialog);
|
||||||
final ProgressDialog progressDialog = new ProgressDialog(LoginFragment.this.getContext(),
|
progressDialog.setIndeterminate(true);
|
||||||
R.style.FUTheme_Dialog);
|
progressDialog.setMessage("Authenticating...");
|
||||||
progressDialog.setIndeterminate(true);
|
progressDialog.show();
|
||||||
progressDialog.setMessage("Authenticating...");
|
|
||||||
progressDialog.show();
|
|
||||||
|
|
||||||
|
|
||||||
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
|
EditText input_usr = ((View) view.getParent()).findViewById(R.id.input_username);
|
||||||
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
|
EditText input_pwd = ((View) view.getParent()).findViewById(R.id.input_password);
|
||||||
if (input_usr != null) {
|
if (input_usr != null) {
|
||||||
if (input_pwd != null) {
|
if (input_pwd != null) {
|
||||||
if (LoginFragment.this.getActivity() == null) {
|
if (LoginFragment.this.getActivity() == null) {
|
||||||
log.e("Login fragment has no activity!");
|
log.e("Login fragment has no activity!");
|
||||||
return;
|
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, new NetworkCallback<LoginToken>() {
|
|
||||||
@Override
|
|
||||||
public void onResponse(@NonNull LoginToken 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, new NetworkErrorCallback() {
|
|
||||||
@Override
|
|
||||||
public void onError(NetworkError error) {
|
|
||||||
progressDialog.dismiss();
|
|
||||||
log.e("error", error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -13,11 +13,7 @@ import android.view.ViewGroup;
|
|||||||
|
|
||||||
import de.sebse.fuplanner.MainActivity;
|
import de.sebse.fuplanner.MainActivity;
|
||||||
import de.sebse.fuplanner.R;
|
import de.sebse.fuplanner.R;
|
||||||
import de.sebse.fuplanner.services.KVV.Modules;
|
|
||||||
import de.sebse.fuplanner.tools.logging.Logger;
|
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.
|
* A fragment representing a list of Items.
|
||||||
@@ -75,18 +71,10 @@ public class ModulesFragment extends Fragment {
|
|||||||
|
|
||||||
|
|
||||||
if (getActivity() != null) {
|
if (getActivity() != null) {
|
||||||
((MainActivity) getActivity()).getKVV().getModuleList(new NetworkCallback<Modules>() {
|
((MainActivity) getActivity()).getKVV().getModuleList(success -> {
|
||||||
@Override
|
log.d(success);
|
||||||
public void onResponse(@NonNull Modules success) {
|
adapter.setModules(success);
|
||||||
log.d(success);
|
}, error -> Log.e("ModFrag", error.toString()));
|
||||||
adapter.setModules(success);
|
|
||||||
}
|
|
||||||
}, new NetworkErrorCallback() {
|
|
||||||
@Override
|
|
||||||
public void onError(NetworkError error) {
|
|
||||||
Log.e("ModFrag", error.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return view;
|
return view;
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.sebse.fuplanner.fragments;
|
package de.sebse.fuplanner.fragments;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@@ -31,29 +32,28 @@ public class ModulesRecyclerViewAdapter extends RecyclerView.Adapter<ModulesRecy
|
|||||||
this.notifyDataSetChanged();
|
this.notifyDataSetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
View view = LayoutInflater.from(parent.getContext())
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.fragment_modules, parent, false);
|
.inflate(R.layout.fragment_modules, parent, false);
|
||||||
return new ViewHolder(view);
|
return new ViewHolder(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(final ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {
|
||||||
if (mValues == null)
|
if (mValues == null)
|
||||||
return;
|
return;
|
||||||
|
position = holder.getAdapterPosition();
|
||||||
holder.mItemPosition = position;
|
holder.mItemPosition = position;
|
||||||
holder.mIdView.setText(mValues.get(position).semester);
|
holder.mIdView.setText(mValues.get(position).semester);
|
||||||
holder.mContentView.setText(mValues.get(position).title);
|
holder.mContentView.setText(mValues.get(position).title);
|
||||||
|
|
||||||
holder.mView.setOnClickListener(new View.OnClickListener() {
|
holder.mView.setOnClickListener(v -> {
|
||||||
@Override
|
if (null != mListener) {
|
||||||
public void onClick(View v) {
|
// Notify the active callbacks interface (the activity, if the
|
||||||
if (null != mListener) {
|
// fragment is attached to one) that an item has been selected.
|
||||||
// Notify the active callbacks interface (the activity, if the
|
mListener.onModulesFragmentInteraction(holder.mItemPosition);
|
||||||
// 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) {
|
public ViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
mView = view;
|
mView = view;
|
||||||
mIdView = (TextView) view.findViewById(R.id.id);
|
mIdView = view.findViewById(R.id.id);
|
||||||
mContentView = (TextView) view.findViewById(R.id.content);
|
mContentView = view.findViewById(R.id.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package de.sebse.fuplanner.fragments;
|
package de.sebse.fuplanner.fragments;
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
@@ -13,9 +11,6 @@ import de.sebse.fuplanner.R;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* 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
|
* Use the {@link StartupFragment#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package de.sebse.fuplanner.fragments.moddetails;
|
package de.sebse.fuplanner.fragments.moddetails;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.support.v4.app.FragmentManager;
|
||||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package de.sebse.fuplanner.fragments.moddetails;
|
|||||||
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v4.app.Fragment;
|
import android.support.v4.app.Fragment;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -54,7 +55,7 @@ public class ModDetailAnnounceFragment extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
// Inflate the layout for this fragment
|
// Inflate the layout for this fragment
|
||||||
return inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
|
return inflater.inflate(R.layout.fragment_mod_detail_announce, container, false);
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ public class ModDetailFragment extends Fragment {
|
|||||||
private int mItemPos;
|
private int mItemPos;
|
||||||
|
|
||||||
private OnModuleDetailFragmentInteractionListener mListener;
|
private OnModuleDetailFragmentInteractionListener mListener;
|
||||||
private ModDetailAdapter adapterViewPager;
|
|
||||||
private Logger log = new Logger(this);
|
private Logger log = new Logger(this);
|
||||||
|
|
||||||
public ModDetailFragment() {
|
public ModDetailFragment() {
|
||||||
@@ -71,8 +70,8 @@ public class ModDetailFragment extends Fragment {
|
|||||||
log.d("on create view");
|
log.d("on create view");
|
||||||
View v = inflater.inflate(R.layout.fragment_mod_detail, container, false);
|
View v = inflater.inflate(R.layout.fragment_mod_detail, container, false);
|
||||||
|
|
||||||
ViewPager vpPager = (ViewPager) v.findViewById(R.id.vpPager);
|
ViewPager vpPager = v.findViewById(R.id.vpPager);
|
||||||
adapterViewPager = new ModDetailAdapter(getFragmentManager(), mItemPos, getContext());
|
ModDetailAdapter adapterViewPager = new ModDetailAdapter(getFragmentManager(), mItemPos, getContext());
|
||||||
vpPager.setAdapter(adapterViewPager);
|
vpPager.setAdapter(adapterViewPager);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
package de.sebse.fuplanner.fragments.moddetails;
|
package de.sebse.fuplanner.fragments.moddetails;
|
||||||
|
|
||||||
import android.icu.text.DateFormat;
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import java.util.Date;
|
import com.ms.square.android.expandabletextview.ExpandableTextView;
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import de.sebse.fuplanner.R;
|
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.Announcement;
|
||||||
|
import de.sebse.fuplanner.services.KVV.Assignment;
|
||||||
import de.sebse.fuplanner.services.KVV.Modules;
|
import de.sebse.fuplanner.services.KVV.Modules;
|
||||||
import de.sebse.fuplanner.tools.Conversion;
|
import de.sebse.fuplanner.tools.Conversion;
|
||||||
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
import de.sebse.fuplanner.tools.ui.CustomViewHolder;
|
||||||
|
|
||||||
public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
|
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 Modules.Module mValue;
|
||||||
//private final ModulesFragment.OnModulesFragmentInteractionListener mListener;
|
//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) {
|
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
View view;
|
View view;
|
||||||
switch (viewType) {
|
switch (viewType) {
|
||||||
case 0:
|
case TYPE_HEADER:
|
||||||
view = LayoutInflater.from(parent.getContext())
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_all_caption, parent, false);
|
.inflate(R.layout.list_all_caption, parent, false);
|
||||||
return new HeaderViewHolder(view);
|
return new HeaderViewHolder(view);
|
||||||
case 1:
|
case TYPE_DESCRIPTION:
|
||||||
view = LayoutInflater.from(parent.getContext())
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_moddetails_description, parent, false);
|
.inflate(R.layout.list_moddetails_description, parent, false);
|
||||||
return new DescriptionViewHolder(view);
|
return new DescriptionViewHolder(view);
|
||||||
case 2:
|
case TYPE_ITEM:
|
||||||
view = LayoutInflater.from(parent.getContext())
|
view = LayoutInflater.from(parent.getContext())
|
||||||
.inflate(R.layout.list_moddetails_announcements, parent, false);
|
.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:
|
default:
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
return null;
|
return null;
|
||||||
@@ -62,39 +67,61 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
|||||||
// Just as an example, return 0 or 2 depending on position
|
// Just as an example, return 0 or 2 depending on position
|
||||||
// Note that unlike in ListView adapters, types don't have to be contiguous
|
// Note that unlike in ListView adapters, types don't have to be contiguous
|
||||||
if (position < 3)
|
if (position < 3)
|
||||||
return position % 2;
|
return position % 2; // HEADER, DESCRIPTION, HEADER
|
||||||
else
|
int count = 2;
|
||||||
return 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
|
@Override
|
||||||
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, int position) {
|
||||||
if (mValue == null)
|
if (mValue == null)
|
||||||
return;
|
return;
|
||||||
int announce_count = getAnnounceCount(2);
|
|
||||||
if (position == 0) {
|
if (position == 0) {
|
||||||
HeaderViewHolder h = (HeaderViewHolder) holder;
|
HeaderViewHolder h = (HeaderViewHolder) holder;
|
||||||
h.mCaption.setText(h.mView.getResources().getText(R.string.description));
|
h.mCaption.setText(R.string.description);
|
||||||
} else if (position == 1) {
|
} else if (position == 1) {
|
||||||
DescriptionViewHolder d = (DescriptionViewHolder) holder;
|
DescriptionViewHolder d = (DescriptionViewHolder) holder;
|
||||||
d.mText.setText(mValue.description);
|
d.mText.setText(mValue.description);
|
||||||
//d.mText.setText(d.mView.getResources().getText(R.string.app_name));
|
|
||||||
} else if (position == 2) {
|
} else if (position == 2) {
|
||||||
HeaderViewHolder h = (HeaderViewHolder) holder;
|
HeaderViewHolder h = (HeaderViewHolder) holder;
|
||||||
h.mCaption.setText(h.mView.getResources().getString(R.string.announcements_count, getAnnounceCount()));
|
h.mCaption.setText(h.mView.getResources().getString(R.string.announcements_count, getAnnounceCount()));
|
||||||
} else if (position <= announce_count+2) {
|
} else if (position <= getAnnounceCount(2)+2) {
|
||||||
AnnounceViewHolder a = (AnnounceViewHolder) holder;
|
ItemViewHolder a = (ItemViewHolder) holder;
|
||||||
Announcement announce = mValue.announcements.get(position - 3);
|
Announcement announce = mValue.announcements.get(position - 3);
|
||||||
a.mTitle.setText(announce.getTitle());
|
a.mTitle.setText(announce.getTitle());
|
||||||
a.mPublisher.setText(announce.getCreatedBy());
|
a.mSubLeft.setText(announce.getCreatedBy());
|
||||||
a.mDate.setText(Conversion.getModifiedDate(announce.getCreatedOn()));
|
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
|
@Override
|
||||||
public int getItemCount() {
|
public int getItemCount() {
|
||||||
if (mValue != null) {
|
if (mValue != null) {
|
||||||
return 3+getAnnounceCount();
|
return 4+getAnnounceCount(3)+getAssignmentCount(3);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -109,6 +136,16 @@ public class ModDetailOverviewAdapter extends RecyclerView.Adapter<RecyclerView.
|
|||||||
return Math.min(max, getAnnounceCount());
|
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 {
|
public class DescriptionViewHolder extends CustomViewHolder {
|
||||||
final TextView mText;
|
final ExpandableTextView mText;
|
||||||
|
|
||||||
DescriptionViewHolder(View view) {
|
DescriptionViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
mText = view.findViewById(R.id.description);
|
mText = view.findViewById(R.id.expand_text_view);//.findViewById(R.id.description);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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 mTitle;
|
||||||
final TextView mPublisher;
|
final TextView mSubLeft;
|
||||||
final TextView mDate;
|
final TextView mSubRight;
|
||||||
|
|
||||||
AnnounceViewHolder(View view) {
|
ItemViewHolder(View view) {
|
||||||
super(view);
|
super(view);
|
||||||
mTitle = view.findViewById(R.id.title);
|
mTitle = view.findViewById(R.id.title);
|
||||||
mPublisher = view.findViewById(R.id.publisher);
|
mSubLeft = view.findViewById(R.id.sub_left);
|
||||||
mDate = view.findViewById(R.id.date);
|
mSubRight = view.findViewById(R.id.sub_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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.v4.app.Fragment;
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
import android.support.v7.widget.LinearLayoutManager;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import de.sebse.fuplanner.MainActivity;
|
import de.sebse.fuplanner.MainActivity;
|
||||||
import de.sebse.fuplanner.R;
|
import de.sebse.fuplanner.R;
|
||||||
import de.sebse.fuplanner.fragments.ModulesRecyclerViewAdapter;
|
|
||||||
import de.sebse.fuplanner.services.KVV.KVV;
|
import de.sebse.fuplanner.services.KVV.KVV;
|
||||||
import de.sebse.fuplanner.services.KVV.Modules;
|
import de.sebse.fuplanner.services.KVV.Modules;
|
||||||
import de.sebse.fuplanner.tools.logging.Logger;
|
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.
|
* A simple {@link Fragment} subclass.
|
||||||
@@ -31,6 +26,7 @@ public class ModDetailOverviewFragment extends Fragment {
|
|||||||
// TODO: Rename parameter arguments, choose names that match
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
private static final String ARG_POSITION = "itemPosition";
|
private static final String ARG_POSITION = "itemPosition";
|
||||||
|
private static Logger slog = new Logger(ModDetailOverviewFragment.class);
|
||||||
|
|
||||||
// TODO: Rename and change types of parameters
|
// TODO: Rename and change types of parameters
|
||||||
private int mItemPos;
|
private int mItemPos;
|
||||||
@@ -54,8 +50,7 @@ public class ModDetailOverviewFragment extends Fragment {
|
|||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
args.putInt(ARG_POSITION, itemPosition);
|
args.putInt(ARG_POSITION, itemPosition);
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
String s = "ModDetailOverviewFragment".toString();
|
slog.d("new Instance");
|
||||||
Log.d(s, "new Instance");
|
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ package de.sebse.fuplanner.services.GoogleAuth;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public interface ConnectedListener {
|
public interface ConnectedListener {
|
||||||
public void connected();
|
void connected();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ package de.sebse.fuplanner.services.GoogleAuth;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public interface CredentialsListener {
|
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.Intent;
|
||||||
import android.content.IntentSender;
|
import android.content.IntentSender;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.support.v4.app.FragmentActivity;
|
||||||
import android.util.Log;
|
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.Credential;
|
||||||
import com.google.android.gms.auth.api.credentials.CredentialRequest;
|
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.CredentialsClient;
|
||||||
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
|
import com.google.android.gms.auth.api.credentials.CredentialsOptions;
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
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.ApiException;
|
||||||
import com.google.android.gms.common.api.CommonStatusCodes;
|
import com.google.android.gms.common.api.CommonStatusCodes;
|
||||||
import com.google.android.gms.common.api.ResolvableApiException;
|
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;
|
import static android.app.Activity.RESULT_OK;
|
||||||
|
|
||||||
@@ -65,38 +61,35 @@ public class GoogleAuth {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
mCredentialsClient.request(request).addOnCompleteListener(new OnCompleteListener<CredentialRequestResponse>() {
|
mCredentialsClient.request(request).addOnCompleteListener(task -> {
|
||||||
@Override
|
if (task.isSuccessful()) {
|
||||||
public void onComplete(@NonNull Task<CredentialRequestResponse> task) {
|
// Successfully read the credential without any user interaction, this
|
||||||
if (task.isSuccessful()) {
|
// means there was only a single credential and the user has auto
|
||||||
// Successfully read the credential without any user interaction, this
|
// sign-in enabled.
|
||||||
// means there was only a single credential and the user has auto
|
Credential credential = task.getResult().getCredential();
|
||||||
// sign-in enabled.
|
credentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
|
||||||
Credential credential = task.getResult().getCredential();
|
return;
|
||||||
credentialsListener.onCredentials(new Credentials(credential.getId(), credential.getPassword()));
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exception e = task.getException();
|
Exception e = task.getException();
|
||||||
if (e instanceof ResolvableApiException) {
|
if (e instanceof ResolvableApiException) {
|
||||||
// This is most likely the case where the user has multiple saved
|
// This is most likely the case where the user has multiple saved
|
||||||
// credentials and needs to pick one. This requires showing UI to
|
// credentials and needs to pick one. This requires showing UI to
|
||||||
// resolve the read request.
|
// resolve the read request.
|
||||||
GoogleAuth.this.mCredentialsListener = credentialsListener;
|
GoogleAuth.this.mCredentialsListener = credentialsListener;
|
||||||
ResolvableApiException rae = (ResolvableApiException) e;
|
ResolvableApiException rae = (ResolvableApiException) e;
|
||||||
resolveResult(rae, RequestCode.RC_READ);
|
resolveResult(rae, RequestCode.RC_READ);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e instanceof ApiException) {
|
if (e instanceof ApiException) {
|
||||||
ApiException ae = (ApiException) e;
|
ApiException ae = (ApiException) e;
|
||||||
if (ae.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED) {
|
if (ae.getStatusCode() == CommonStatusCodes.SIGN_IN_REQUIRED) {
|
||||||
// This means only a hint is available, but we are handling that
|
// This means only a hint is available, but we are handling that
|
||||||
// elsewhere so no need to act here.
|
// elsewhere so no need to act here.
|
||||||
} else {
|
} else {
|
||||||
credentialsListener.onCredentials(null);
|
credentialsListener.onCredentials(null);
|
||||||
Log.w(TAG, "Unexpected status code: " + ae.getStatusCode());
|
Log.w(TAG, "Unexpected status code: " + ae.getStatusCode());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -111,25 +104,22 @@ public class GoogleAuth {
|
|||||||
Credential credential = new Credential.Builder(username)
|
Credential credential = new Credential.Builder(username)
|
||||||
.setPassword(password)
|
.setPassword(password)
|
||||||
.build();
|
.build();
|
||||||
mCredentialsClient.save(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
|
mCredentialsClient.save(credential).addOnCompleteListener(task -> {
|
||||||
@Override
|
if (task.isSuccessful()) {
|
||||||
public void onComplete(@NonNull Task<Void> task) {
|
showToast("Credential saved.");
|
||||||
if (task.isSuccessful()) {
|
return;
|
||||||
showToast("Credential saved.");
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Exception e = task.getException();
|
Exception e = task.getException();
|
||||||
if (e instanceof ResolvableApiException) {
|
if (e instanceof ResolvableApiException) {
|
||||||
// The first time a credential is saved, the user is shown UI
|
// The first time a credential is saved, the user is shown UI
|
||||||
// to confirm the action. This requires resolution.
|
// to confirm the action. This requires resolution.
|
||||||
ResolvableApiException rae = (ResolvableApiException) e;
|
ResolvableApiException rae = (ResolvableApiException) e;
|
||||||
resolveResult(rae, RequestCode.RC_SAVE);
|
resolveResult(rae, RequestCode.RC_SAVE);
|
||||||
} else {
|
} else {
|
||||||
// Save failure cannot be resolved.
|
// Save failure cannot be resolved.
|
||||||
Log.w(TAG, "Save failed.", e);
|
Log.w(TAG, "Save failed.", e);
|
||||||
showToast("Credential Save Failed");
|
showToast("Credential Save Failed");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -142,12 +132,9 @@ public class GoogleAuth {
|
|||||||
Credential credential = new Credential.Builder(username)
|
Credential credential = new Credential.Builder(username)
|
||||||
.setPassword(password)
|
.setPassword(password)
|
||||||
.build();
|
.build();
|
||||||
mCredentialsClient.delete(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
|
mCredentialsClient.delete(credential).addOnCompleteListener(task -> {
|
||||||
@Override
|
if (task.isSuccessful()) {
|
||||||
public void onComplete(@NonNull Task<Void> task) {
|
// Credential was deleted successfully
|
||||||
if (task.isSuccessful()) {
|
|
||||||
// Credential was deleted successfully
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
package de.sebse.fuplanner.services.KVV;
|
package de.sebse.fuplanner.services.KVV;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.volley.Response;
|
|
||||||
import com.android.volley.VolleyError;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
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.NetworkCallback;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
import de.sebse.fuplanner.tools.network.NetworkError;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||||
import de.sebse.fuplanner.tools.network.Result;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by sebastian on 24.10.17.
|
* Created by sebastian on 24.10.17.
|
||||||
@@ -53,29 +48,21 @@ class KVVLogin extends HTTPService {
|
|||||||
-> JSESSIONID 5c10406f-588c-4c16-96e9-c80d115417de.tomcat1
|
-> JSESSIONID 5c10406f-588c-4c16-96e9-c80d115417de.tomcat1
|
||||||
*/
|
*/
|
||||||
private void startKVVSession(final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
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>() {
|
get("https://kvv.imp.fu-berlin.de/portal/login", null, response -> {
|
||||||
@Override
|
String cookies = response.getHeaders().get("Set-Cookie");
|
||||||
public void onResponse(Result response) {
|
if (cookies==null) {
|
||||||
String cookies = response.getHeaders().get("Set-Cookie");
|
errorCallback.onError(new NetworkError(100101, -1, "Error on starting KVV session!"));
|
||||||
if (cookies==null) {
|
return;
|
||||||
errorCallback.onError(new NetworkError(100101, -1, "Error on starting KVV session!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HashMap<String, String> object;
|
|
||||||
try {
|
|
||||||
object = getCookie(cookies, new String[]{"JSESSIONID"});
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
errorCallback.onError(new NetworkError(100102, -1, "Error on starting KVV session!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onResponse(object);
|
|
||||||
}
|
}
|
||||||
}, new Response.ErrorListener() {
|
HashMap<String, String> object;
|
||||||
@Override
|
try {
|
||||||
public void onErrorResponse(VolleyError error) {
|
object = getCookie(cookies, new String[]{"JSESSIONID"});
|
||||||
errorCallback.onError(new NetworkError(100100, error.networkResponse.statusCode, "Error on starting KVV session!"));
|
} catch (NoSuchFieldException e) {
|
||||||
|
errorCallback.onError(new NetworkError(100102, -1, "Error on starting KVV session!"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
callback.onResponse(object);
|
||||||
|
}, error -> errorCallback.onError(new NetworkError(100100, error.networkResponse.statusCode, "Error on starting KVV session!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -88,24 +75,16 @@ class KVVLogin extends HTTPService {
|
|||||||
private void getSAMLRequest(String JSESSIONID, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
private void getSAMLRequest(String JSESSIONID, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||||
HashMap<String, String> cookies = new HashMap<>();
|
HashMap<String, String> cookies = new HashMap<>();
|
||||||
cookies.put("JSESSIONID", JSESSIONID);
|
cookies.put("JSESSIONID", JSESSIONID);
|
||||||
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", cookies, new Response.Listener<Result>() {
|
get("https://kvv.imp.fu-berlin.de/sakai-login-tool/container", cookies, response -> {
|
||||||
@Override
|
String location = response.getHeaders().get("Location");
|
||||||
public void onResponse(Result response) {
|
if (location==null) {
|
||||||
String location = response.getHeaders().get("Location");
|
errorCallback.onError(new NetworkError(100111, -1, "Error on getting SAML request!"));
|
||||||
if (location==null) {
|
return;
|
||||||
errorCallback.onError(new NetworkError(100111, -1, "Error on getting SAML request!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HashMap<String, String> object = new HashMap<>();
|
|
||||||
object.put("Location", location);
|
|
||||||
callback.onResponse(object);
|
|
||||||
}
|
}
|
||||||
}, new Response.ErrorListener() {
|
HashMap<String, String> object = new HashMap<>();
|
||||||
@Override
|
object.put("Location", location);
|
||||||
public void onErrorResponse(VolleyError error) {
|
callback.onResponse(object);
|
||||||
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,29 +96,21 @@ class KVVLogin extends HTTPService {
|
|||||||
-> ROUTEID .1
|
-> ROUTEID .1
|
||||||
*/
|
*/
|
||||||
private void startIdentSession(String url, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
private void startIdentSession(String url, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
||||||
get(url, null, new Response.Listener<Result>() {
|
get(url, null, response -> {
|
||||||
@Override
|
String cookies = response.getHeaders().get("Set-Cookie");
|
||||||
public void onResponse(Result response) {
|
if (cookies==null) {
|
||||||
String cookies = response.getHeaders().get("Set-Cookie");
|
errorCallback.onError(new NetworkError(100121, -1, "Error on starting Ident session!"));
|
||||||
if (cookies==null) {
|
return;
|
||||||
errorCallback.onError(new NetworkError(100121, -1, "Error on starting Ident session!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HashMap<String, String> object;
|
|
||||||
try {
|
|
||||||
object = getCookie(cookies, new String[]{"JSESSIONID", "_idp_authn_lc_key", "ROUTEID"});
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
errorCallback.onError(new NetworkError(100122, -1, "Error on starting Ident session!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback.onResponse(object);
|
|
||||||
}
|
}
|
||||||
}, new Response.ErrorListener() {
|
HashMap<String, String> object;
|
||||||
@Override
|
try {
|
||||||
public void onErrorResponse(VolleyError error) {
|
object = getCookie(cookies, new String[]{"JSESSIONID", "_idp_authn_lc_key", "ROUTEID"});
|
||||||
errorCallback.onError(new NetworkError(100120, error.networkResponse.statusCode, "Error on starting Ident session!"));
|
} catch (NoSuchFieldException e) {
|
||||||
|
errorCallback.onError(new NetworkError(100122, -1, "Error on starting Ident session!"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
callback.onResponse(object);
|
||||||
|
}, 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<>();
|
HashMap<String, String> body = new HashMap<>();
|
||||||
body.put("j_username", username);
|
body.put("j_username", username);
|
||||||
body.put("j_password", password);
|
body.put("j_password", password);
|
||||||
post("https://identity.fu-berlin.de/idp-fub/Authn/UserPassword", cookies, body, new Response.Listener<Result>() {
|
post("https://identity.fu-berlin.de/idp-fub/Authn/UserPassword", cookies, body, response -> {
|
||||||
@Override
|
if (first) {
|
||||||
public void onResponse(Result response) {
|
callback.onResponse(new HashMap<>());
|
||||||
if (first) {
|
return;
|
||||||
callback.onResponse(new HashMap<String, String>());
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String cookies = response.getHeaders().get("Set-Cookie");
|
String cookies1 = response.getHeaders().get("Set-Cookie");
|
||||||
if (cookies==null) {
|
if (cookies1 ==null) {
|
||||||
errorCallback.onError(new NetworkError(100131, -1, "Error on logging in to Identity Server!"));
|
errorCallback.onError(new NetworkError(100131, -1, "Error on logging in to Identity Server!"));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
HashMap<String, String> object;
|
|
||||||
try {
|
|
||||||
object = getCookie(cookies, 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() {
|
HashMap<String, String> object;
|
||||||
@Override
|
try {
|
||||||
public void onErrorResponse(VolleyError error) {
|
object = getCookie(cookies1, new String[]{"_idp_session"});
|
||||||
errorCallback.onError(new NetworkError(100130, error.networkResponse.statusCode, "Error on logging in to Identity Server!"));
|
} catch (NoSuchFieldException e) {
|
||||||
|
errorCallback.onError(new NetworkError(100132, -1, "Error on logging in to Identity Server!"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
callback.onResponse(object);
|
||||||
|
}, error -> errorCallback.onError(new NetworkError(100130, error.networkResponse.statusCode, "Error on logging in to Identity Server!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -205,35 +168,27 @@ class KVVLogin extends HTTPService {
|
|||||||
cookies.put("_idp_authn_lc_key", _idp_authn_lc_key);
|
cookies.put("_idp_authn_lc_key", _idp_authn_lc_key);
|
||||||
cookies.put("ROUTEID", ROUTEID);
|
cookies.put("ROUTEID", ROUTEID);
|
||||||
cookies.put("_idp_session", _idp_session);
|
cookies.put("_idp_session", _idp_session);
|
||||||
get("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO", cookies, new Response.Listener<Result>() {
|
get("https://identity.fu-berlin.de/idp-fub/profile/SAML2/Redirect/SSO", cookies, response -> {
|
||||||
@Override
|
HashMap<String, String> object = new HashMap<>();
|
||||||
public void onResponse(Result response) {
|
|
||||||
HashMap<String, String> object = new HashMap<>();
|
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile("ss:mem:([0-9a-f]+)");
|
Pattern pattern = Pattern.compile("ss:mem:([0-9a-f]+)");
|
||||||
Matcher matcher = pattern.matcher(response.getParsed());
|
Matcher matcher = pattern.matcher(response.getParsed());
|
||||||
if (!matcher.find()) {
|
if (!matcher.find()) {
|
||||||
errorCallback.onError(new NetworkError(100142, -1, "Error on getting SAML response!"));
|
errorCallback.onError(new NetworkError(100142, -1, "Error on getting SAML response!"));
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
object.put("RelayState", "ss:mem:"+matcher.group(1));
|
|
||||||
|
|
||||||
pattern = Pattern.compile("([0-9a-zA-Z+]+==)");
|
|
||||||
matcher = pattern.matcher(response.getParsed());
|
|
||||||
if (!matcher.find()) {
|
|
||||||
errorCallback.onError(new NetworkError(100141, -1, "Error on getting SAML response!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
object.put("SAMLResponse", matcher.group(1));
|
|
||||||
|
|
||||||
callback.onResponse(object);
|
|
||||||
}
|
}
|
||||||
}, new Response.ErrorListener() {
|
object.put("RelayState", "ss:mem:"+matcher.group(1));
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
pattern = Pattern.compile("([0-9a-zA-Z+]+==)");
|
||||||
errorCallback.onError(new NetworkError(100140, error.networkResponse.statusCode, "Error on getting SAML response!"));
|
matcher = pattern.matcher(response.getParsed());
|
||||||
|
if (!matcher.find()) {
|
||||||
|
errorCallback.onError(new NetworkError(100141, -1, "Error on getting SAML response!"));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
object.put("SAMLResponse", matcher.group(1));
|
||||||
|
|
||||||
|
callback.onResponse(object);
|
||||||
|
}, error -> errorCallback.onError(new NetworkError(100140, error.networkResponse.statusCode, "Error on getting SAML response!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -251,33 +206,25 @@ class KVVLogin extends HTTPService {
|
|||||||
HashMap<String, String> body = new HashMap<>();
|
HashMap<String, String> body = new HashMap<>();
|
||||||
body.put("RelayState", RelayState);
|
body.put("RelayState", RelayState);
|
||||||
body.put("SAMLResponse", SAMLResponse);
|
body.put("SAMLResponse", SAMLResponse);
|
||||||
post("https://kvv.imp.fu-berlin.de/Shibboleth.sso/SAML2/POST", cookies, body, new Response.Listener<Result>() {
|
post("https://kvv.imp.fu-berlin.de/Shibboleth.sso/SAML2/POST", cookies, body, response -> {
|
||||||
@Override
|
String cookies1 = response.getHeaders().get("Set-Cookie");
|
||||||
public void onResponse(Result response) {
|
if (cookies1 ==null) {
|
||||||
String cookies = response.getHeaders().get("Set-Cookie");
|
errorCallback.onError(new NetworkError(100151, -1, "Error on starting KVV session!"));
|
||||||
if (cookies==null) {
|
return;
|
||||||
errorCallback.onError(new NetworkError(100151, -1, "Error on starting KVV session!"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
HashMap<String, String> object = new HashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
Pattern pattern = Pattern.compile("(_shibsession_[0-9a-f]+)=([^;]+);");
|
|
||||||
Matcher matcher = pattern.matcher(cookies);
|
|
||||||
if (!matcher.find()) {
|
|
||||||
errorCallback.onError(new NetworkError(100152, -1, "Error on starting Ident session!"));
|
|
||||||
}
|
|
||||||
object.put("shibsessionKey", matcher.group(1));
|
|
||||||
object.put("shibsessionName", matcher.group(2));
|
|
||||||
|
|
||||||
callback.onResponse(object);
|
|
||||||
}
|
}
|
||||||
}, new Response.ErrorListener() {
|
HashMap<String, String> object = new HashMap<>();
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
errorCallback.onError(new NetworkError(100150, error.networkResponse.statusCode, "Error on starting Ident session!"));
|
Pattern pattern = Pattern.compile("(_shibsession_[0-9a-f]+)=([^;]+);");
|
||||||
|
Matcher matcher = pattern.matcher(cookies1);
|
||||||
|
if (!matcher.find()) {
|
||||||
|
errorCallback.onError(new NetworkError(100152, -1, "Error on starting Ident session!"));
|
||||||
}
|
}
|
||||||
});
|
object.put("shibsessionKey", matcher.group(1));
|
||||||
|
object.put("shibsessionName", matcher.group(2));
|
||||||
|
|
||||||
|
callback.onResponse(object);
|
||||||
|
}, error -> errorCallback.onError(new NetworkError(100150, error.networkResponse.statusCode, "Error on starting Ident session!")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -288,17 +235,7 @@ class KVVLogin extends HTTPService {
|
|||||||
_b1912c5a03d733a80bd3fee772bf68d4
|
_b1912c5a03d733a80bd3fee772bf68d4
|
||||||
*/
|
*/
|
||||||
private void finishKVVlogin(LoginToken loginToken, final NetworkCallback<HashMap<String, String>> callback, final NetworkErrorCallback errorCallback) {
|
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>() {
|
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!")));
|
||||||
@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!"));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public class KVVModuleList extends HTTPService {
|
|||||||
get("https://kvv.imp.fu-berlin.de/direct/site.json", token.getCookies(), response -> {
|
get("https://kvv.imp.fu-berlin.de/direct/site.json", token.getCookies(), response -> {
|
||||||
String body = response.getParsed();
|
String body = response.getParsed();
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
errorCallback.onError(new NetworkError(101101, 403, "No module list retreived!"));
|
errorCallback.onError(new NetworkError(101101, 403, "No module list retrieved!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Modules modules = new Modules();
|
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) {
|
public void getModule(int index, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
||||||
this.getModuleList(success -> {
|
this.getModuleList(success -> callback.onResponse(success.get(index)), errorCallback);
|
||||||
callback.onResponse(success.get(index));
|
|
||||||
}, errorCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void getAnnouncements(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
public void getAnnouncements(Modules.Module module, final NetworkCallback<Modules.Module> callback, final NetworkErrorCallback errorCallback) {
|
||||||
queueModuleDetails.add(module.getID(), () -> {
|
queueModuleDetails.add(module.getID(), () -> {
|
||||||
if (module.announcements != null) {
|
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 -> {
|
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();
|
String body = response.getParsed();
|
||||||
if (body == null) {
|
if (body == null) {
|
||||||
errorCallback.onError(new NetworkError(101201, 403, "No announcements retreived!"));
|
errorCallback.onError(new NetworkError(101201, 403, "No announcements retrieved!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ArrayList<Announcement> announcements = new ArrayList<>();
|
ArrayList<Announcement> announcements = new ArrayList<>();
|
||||||
@@ -129,4 +132,28 @@ public class KVVModuleList extends HTTPService {
|
|||||||
callback.onResponse(announcements);
|
callback.onResponse(announcements);
|
||||||
}, error -> errorCallback.onError(new NetworkError(101203, error.networkResponse.statusCode, "Cannot get 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();
|
int size = list.size();
|
||||||
do {
|
do {
|
||||||
next++;
|
next++;
|
||||||
} while (next < size && !accept(list.get(next)));
|
} while (next < size && decline(list.get(next)));
|
||||||
if (next == size)
|
if (next == size)
|
||||||
next = -1;
|
next = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean accept(Module ob){
|
private boolean decline(Module ob){
|
||||||
return ob.semester.equals(latestSemester);
|
return !ob.semester.equals(latestSemester);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -188,6 +188,7 @@ public class Modules /*extends EventEmitter<Triplet<Integer, Modules.UpgradeModu
|
|||||||
public final String description;
|
public final String description;
|
||||||
private final String ID;
|
private final String ID;
|
||||||
public ArrayList<Announcement> announcements;
|
public ArrayList<Announcement> announcements;
|
||||||
|
public ArrayList<Assignment> assignments;
|
||||||
|
|
||||||
/*private Module() {
|
/*private Module() {
|
||||||
this(null, null, null, null, null);
|
this(null, null, null, null, null);
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import android.util.Log;
|
|||||||
import com.android.volley.AuthFailureError;
|
import com.android.volley.AuthFailureError;
|
||||||
import com.android.volley.Request;
|
import com.android.volley.Request;
|
||||||
import com.android.volley.RequestQueue;
|
import com.android.volley.RequestQueue;
|
||||||
import com.android.volley.Response;
|
|
||||||
import com.android.volley.VolleyError;
|
|
||||||
import com.android.volley.VolleyLog;
|
import com.android.volley.VolleyLog;
|
||||||
import com.android.volley.toolbox.StringRequest;
|
import com.android.volley.toolbox.StringRequest;
|
||||||
import com.android.volley.toolbox.Volley;
|
import com.android.volley.toolbox.Volley;
|
||||||
@@ -35,17 +33,7 @@ public class MensaPlan {
|
|||||||
post.put("date", "2017-10-13");
|
post.put("date", "2017-10-13");
|
||||||
final String requestBody = post.toString();
|
final String requestBody = post.toString();
|
||||||
|
|
||||||
StringRequest request = new StringRequest(Request.Method.POST, "https://www.stw.berlin/xhr/speiseplan-wochentag.html", new Response.Listener<String>() {
|
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 void onResponse(String response) {
|
|
||||||
Log.d("MensaPlan DDDD", response);
|
|
||||||
}
|
|
||||||
}, new Response.ErrorListener() {
|
|
||||||
@Override
|
|
||||||
public void onErrorResponse(VolleyError error) {
|
|
||||||
Log.d("MensaPlan EEEE", error.getMessage());
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
@Override
|
@Override
|
||||||
public String getBodyContentType() {
|
public String getBodyContentType() {
|
||||||
return "application/json; charset=utf-8";
|
return "application/json; charset=utf-8";
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
package de.sebse.fuplanner.tools;
|
package de.sebse.fuplanner.tools;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
import de.sebse.fuplanner.tools.network.NetworkCallback;
|
||||||
import de.sebse.fuplanner.tools.network.NetworkError;
|
|
||||||
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
import de.sebse.fuplanner.tools.network.NetworkErrorCallback;
|
||||||
|
|
||||||
public class AsyncQueue {
|
public class AsyncQueue {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package de.sebse.fuplanner.tools;
|
package de.sebse.fuplanner.tools;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.text.format.DateFormat;
|
import android.text.format.DateFormat;
|
||||||
@@ -16,13 +17,14 @@ public class Conversion {
|
|||||||
return getModifiedDate(Locale.getDefault(), modified);
|
return getModifiedDate(Locale.getDefault(), modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SimpleDateFormat")
|
||||||
public static String getModifiedDate(Locale locale, long modified) {
|
public static String getModifiedDate(Locale locale, long modified) {
|
||||||
SimpleDateFormat dateFormat = null;
|
SimpleDateFormat dateFormat;
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
|
||||||
dateFormat = new SimpleDateFormat(getDateFormat(locale));
|
dateFormat = new SimpleDateFormat(getDateFormat(locale));
|
||||||
} else {
|
} 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));
|
return dateFormat.format(new Date(modified));
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package de.sebse.fuplanner.tools;
|
package de.sebse.fuplanner.tools;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
|
|
||||||
import org.intellij.lang.annotations.Language;
|
import org.intellij.lang.annotations.Language;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -26,38 +24,33 @@ public class Regex {
|
|||||||
|
|
||||||
public static Iterable<MatchResult> allMatches(@Language("Regexp") String regex, final CharSequence input) {
|
public static Iterable<MatchResult> allMatches(@Language("Regexp") String regex, final CharSequence input) {
|
||||||
final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
|
final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
|
||||||
return new Iterable<MatchResult>() {
|
return () -> new Iterator<MatchResult>() {
|
||||||
@NonNull
|
// Use a matcher internally.
|
||||||
public Iterator<MatchResult> iterator() {
|
final Matcher matcher = pattern.matcher(input);
|
||||||
return new Iterator<MatchResult>() {
|
// Keep a match around that supports any interleaving of hasNext/next calls.
|
||||||
// Use a matcher internally.
|
MatchResult pending;
|
||||||
final Matcher matcher = pattern.matcher(input);
|
|
||||||
// Keep a match around that supports any interleaving of hasNext/next calls.
|
|
||||||
MatchResult pending;
|
|
||||||
|
|
||||||
public boolean hasNext() {
|
public boolean hasNext() {
|
||||||
// Lazily fill pending, and avoid calling find() multiple times if the
|
// Lazily fill pending, and avoid calling find() multiple times if the
|
||||||
// clients call hasNext() repeatedly before sampling via next().
|
// clients call hasNext() repeatedly before sampling via next().
|
||||||
if (pending == null && matcher.find()) {
|
if (pending == null && matcher.find()) {
|
||||||
pending = matcher.toMatchResult();
|
pending = matcher.toMatchResult();
|
||||||
}
|
}
|
||||||
return pending != null;
|
return pending != null;
|
||||||
}
|
|
||||||
|
|
||||||
public MatchResult next() {
|
|
||||||
// Fill pending if necessary (as when clients call next() without
|
|
||||||
// checking hasNext()), throw if not possible.
|
|
||||||
if (!hasNext()) { throw new NoSuchElementException(); }
|
|
||||||
// Consume pending so next call to hasNext() does a find().
|
|
||||||
MatchResult next = pending;
|
|
||||||
pending = null;
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Required to satisfy the interface, but unsupported. */
|
|
||||||
public void remove() { throw new UnsupportedOperationException(); }
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MatchResult next() {
|
||||||
|
// Fill pending if necessary (as when clients call next() without
|
||||||
|
// checking hasNext()), throw if not possible.
|
||||||
|
if (!hasNext()) { throw new NoSuchElementException(); }
|
||||||
|
// Consume pending so next call to hasNext() does a find().
|
||||||
|
MatchResult next = pending;
|
||||||
|
pending = null;
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Required to satisfy the interface, but unsupported. */
|
||||||
|
public void remove() { throw new UnsupportedOperationException(); }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ public class BetterHurlStack extends HurlStack {
|
|||||||
|
|
||||||
private final UrlRewriter mUrlRewriter;
|
private final UrlRewriter mUrlRewriter;
|
||||||
private final SSLSocketFactory mSslSocketFactory;
|
private final SSLSocketFactory mSslSocketFactory;
|
||||||
private boolean followRedirects;
|
@SuppressWarnings({"unused", "FieldCanBeLocal"})
|
||||||
|
private boolean followRedirects; // TODO auto-redirect
|
||||||
|
|
||||||
BetterHurlStack() {
|
BetterHurlStack() {
|
||||||
this(true);
|
this(true);
|
||||||
@@ -130,7 +131,7 @@ public class BetterHurlStack extends HurlStack {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes an {@link HttpEntity} from the given {@link HttpURLConnection}.
|
* 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>.
|
* @return an HttpEntity populated with data from <code>connection</code>.
|
||||||
*/
|
*/
|
||||||
private static HttpEntity entityFromConnection(HttpURLConnection connection) {
|
private static HttpEntity entityFromConnection(HttpURLConnection connection) {
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package de.sebse.fuplanner.tools.network;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import com.android.volley.AuthFailureError;
|
import com.android.volley.AuthFailureError;
|
||||||
import com.android.volley.NetworkResponse;
|
import com.android.volley.NetworkResponse;
|
||||||
|
|||||||
@@ -17,7 +17,8 @@
|
|||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="128dp"
|
android:layout_height="128dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:layout_gravity="center_horizontal" />
|
android:layout_gravity="center_horizontal"
|
||||||
|
android:contentDescription="@string/cd_ic_launcher"/>
|
||||||
|
|
||||||
<!-- Email Label -->
|
<!-- Email Label -->
|
||||||
<android.support.design.widget.TextInputLayout
|
<android.support.design.widget.TextInputLayout
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textEmailAddress"
|
android:inputType="textEmailAddress"
|
||||||
android:hint="Username" />
|
android:hint="@string/username" />
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<!-- Password Label -->
|
<!-- Password Label -->
|
||||||
@@ -42,7 +43,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:hint="Password"/>
|
android:hint="@string/password"/>
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<android.support.v7.widget.AppCompatButton
|
<android.support.v7.widget.AppCompatButton
|
||||||
@@ -52,7 +53,7 @@
|
|||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:padding="12dp"
|
android:padding="12dp"
|
||||||
android:text="Login"/>
|
android:text="@string/log_in"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,6 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:text="Announcement fragment" />
|
android:text="@string/lorem_ipsum_100" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
android:layout_width="@android:dimen/thumbnail_width"
|
android:layout_width="@android:dimen/thumbnail_width"
|
||||||
android:layout_height="@android:dimen/thumbnail_height"
|
android:layout_height="@android:dimen/thumbnail_height"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:src="@mipmap/ic_launcher" />
|
android:src="@mipmap/ic_launcher"
|
||||||
|
android:contentDescription="@string/cd_ic_launcher"/>
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -1,14 +1,15 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/caption"
|
android:id="@+id/caption"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/text_margin"
|
android:layout_margin="@dimen/text_margin"
|
||||||
android:text="Caption"
|
tools:text="Caption"
|
||||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline" />
|
||||||
</LinearLayout>
|
</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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:padding="5dip" >
|
android:padding="5dip" >
|
||||||
@@ -15,21 +15,21 @@
|
|||||||
tools:text="Test this new stuff!" />
|
tools:text="Test this new stuff!" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/publisher"
|
android:id="@+id/sub_left"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/title"
|
android:layout_below="@id/title"
|
||||||
android:layout_marginTop="5dip"
|
android:layout_marginTop="5dip"
|
||||||
android:textColor="#343434"
|
android:textColor="#343434"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
tools:text="Peter Müller" />
|
tools:text="Peter Bauer" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/date"
|
android:id="@+id/sub_right"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignBaseline="@+id/publisher"
|
android:layout_alignBaseline="@id/sub_left"
|
||||||
android:layout_alignBottom="@+id/publisher"
|
android:layout_alignBottom="@id/sub_left"
|
||||||
android:textColor="#343434"
|
android:textColor="#343434"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
|
|||||||
@@ -1,14 +1,41 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<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:layout_height="wrap_content"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<TextView
|
<!-- 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:id="@+id/description"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/text_margin"
|
android:layout_margin="@dimen/text_margin"
|
||||||
android:text="@string/lorem_ipsum_100"
|
android:text="@string/lorem_ipsum_100"
|
||||||
android:textAppearance="?attr/textAppearanceListItem" />
|
android:textAppearance="?attr/textAppearanceListItem" />-->
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/nav_header_height"
|
android:layout_height="@dimen/nav_header_height"
|
||||||
android:background="@drawable/side_nav_bar"
|
android:background="@drawable/side_nav_bar"
|
||||||
@@ -17,7 +18,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
style="@style/Widget.AppCompat.Button.Colored"
|
style="@style/Widget.AppCompat.Button.Colored"
|
||||||
android:text="Login"
|
android:text="@string/log_in"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
|
||||||
@@ -27,14 +28,15 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:srcCompat="@mipmap/ic_launcher"
|
app:srcCompat="@mipmap/ic_launcher"
|
||||||
android:visibility="gone" />
|
android:visibility="gone"
|
||||||
|
android:contentDescription="@string/cd_ic_launcher"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/login_name"
|
android:id="@+id/login_name"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
android:paddingTop="@dimen/nav_header_vertical_spacing"
|
||||||
android:text="Android Studio"
|
tools:text="Android Studio"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
</LinearLayout>
|
</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
|
<item
|
||||||
android:id="@+id/nav_dining"
|
android:id="@+id/nav_dining"
|
||||||
android:icon="@drawable/ic_local_dining"
|
android:icon="@drawable/ic_local_dining"
|
||||||
android:title="Mensaplan" />
|
android:title="@string/canteen_plan" />
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<item android:title="Optionen">
|
<item android:title="@string/options">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_share"
|
android:id="@+id/nav_share"
|
||||||
android:icon="@drawable/ic_menu_share"
|
android:icon="@drawable/ic_menu_share"
|
||||||
android:title="Teilen"/>
|
android:title="@string/share"/>
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
|
||||||
|
|||||||
@@ -5,37 +5,37 @@
|
|||||||
<item
|
<item
|
||||||
android:id="@+id/nav_schedule"
|
android:id="@+id/nav_schedule"
|
||||||
android:icon="@drawable/ic_event"
|
android:icon="@drawable/ic_event"
|
||||||
android:title="Stundenplan"
|
android:title="@string/schedule"
|
||||||
android:orderInCategory="10"/>
|
android:orderInCategory="10"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_modules"
|
android:id="@+id/nav_modules"
|
||||||
android:icon="@drawable/ic_apps"
|
android:icon="@drawable/ic_apps"
|
||||||
android:title="Module"
|
android:title="@string/events"
|
||||||
android:orderInCategory="100" />
|
android:orderInCategory="100" />
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_dining"
|
android:id="@+id/nav_dining"
|
||||||
android:icon="@drawable/ic_local_dining"
|
android:icon="@drawable/ic_local_dining"
|
||||||
android:title="Mensaplan"
|
android:title="@string/canteen_plan"
|
||||||
android:orderInCategory="200"/>
|
android:orderInCategory="200"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_settings"
|
android:id="@+id/nav_settings"
|
||||||
android:icon="@drawable/ic_settings"
|
android:icon="@drawable/ic_settings"
|
||||||
android:title="Einstellungen"
|
android:title="@string/settings"
|
||||||
android:orderInCategory="300"/>
|
android:orderInCategory="300"/>
|
||||||
</group>
|
</group>
|
||||||
|
|
||||||
<item android:title="Optionen"
|
<item android:title="@string/options"
|
||||||
android:orderInCategory="499">
|
android:orderInCategory="499">
|
||||||
<menu>
|
<menu>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_logout"
|
android:id="@+id/nav_logout"
|
||||||
android:icon="@drawable/ic_exit_to_app"
|
android:icon="@drawable/ic_exit_to_app"
|
||||||
android:title="Logout"
|
android:title="@string/log_out"
|
||||||
android:orderInCategory="500"/>
|
android:orderInCategory="500"/>
|
||||||
<item
|
<item
|
||||||
android:id="@+id/nav_share"
|
android:id="@+id/nav_share"
|
||||||
android:icon="@drawable/ic_menu_share"
|
android:icon="@drawable/ic_menu_share"
|
||||||
android:title="Teilen"
|
android:title="@string/share"
|
||||||
android:orderInCategory="600"/>
|
android:orderInCategory="600"/>
|
||||||
</menu>
|
</menu>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -7,10 +7,21 @@
|
|||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
|
|
||||||
<!-- TODO: Remove or change this placeholder text -->
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
<string name="hello_blank_fragment">Hello blank fragment</string>
|
|
||||||
<string name="overview">Overview</string>
|
<string name="overview">Overview</string>
|
||||||
<string name="announcements">Announcements</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="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="description">Description</string>
|
||||||
<string name="announcements_count">Announcements (%1$d)</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>
|
</resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user