Compare commits

...

3 Commits

Author SHA1 Message Date
Kacper Ziubryniewicz
8f80bc70ed [Architecture] Implement dagger for homework 2019-11-04 22:13:07 +01:00
Kacper Ziubryniewicz
e1d902ceb5 [Architecture] Migrate homework to MVP 2019-11-04 20:19:50 +01:00
Kacper Ziubryniewicz
eb1984c6b5 [Architecture] Add base MVP classes 2019-11-04 20:18:42 +01:00
26 changed files with 771 additions and 364 deletions

View File

@ -1,6 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'io.fabric'
@ -91,7 +92,7 @@ tasks.whenTaskAdded { task ->
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
annotationProcessor "androidx.room:room-compiler:${versions.room}"
kapt "androidx.room:room-compiler:${versions.room}"
debugImplementation "com.amitshekhar.android:debug-db:1.0.5"
implementation "android.arch.navigation:navigation-fragment-ktx:${versions.navigationFragment}"
@ -164,6 +165,11 @@ dependencies {
implementation "io.github.wulkanowy:signer-android:0.1.1"
implementation "androidx.work:work-runtime-ktx:${versions.work}"
api "com.google.dagger:dagger:${versions.dagger}"
api "com.google.dagger:dagger-android-support:${versions.dagger}"
kapt "com.google.dagger:dagger-compiler:${versions.dagger}"
kapt "com.google.dagger:dagger-android-processor:${versions.dagger}"
}
repositories {
mavenCentral()

View File

@ -22,6 +22,7 @@ import android.util.Pair;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.multidex.MultiDex;
import androidx.work.Configuration;
import com.chuckerteam.chucker.api.ChuckerCollector;
@ -59,6 +60,8 @@ import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import cat.ereza.customactivityoncrash.config.CaocConfig;
import dagger.android.AndroidInjector;
import dagger.android.support.DaggerApplication;
import im.wangchao.mhttp.MHttp;
import im.wangchao.mhttp.internal.cookie.PersistentCookieJar;
import im.wangchao.mhttp.internal.cookie.cache.SetCookieCache;
@ -77,6 +80,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.debuglog.DebugLog;
import pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.Profile;
import pl.szczodrzynski.edziennik.data.db.modules.profiles.ProfileFull;
import pl.szczodrzynski.edziennik.di.DaggerAppComponent;
import pl.szczodrzynski.edziennik.network.NetworkUtils;
import pl.szczodrzynski.edziennik.network.TLSSocketFactory;
import pl.szczodrzynski.edziennik.sync.SyncWorker;
@ -90,7 +94,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_MOBIDZIENNIK;
import static pl.szczodrzynski.edziennik.data.db.modules.login.LoginStore.LOGIN_TYPE_VULCAN;
public class App extends androidx.multidex.MultiDexApplication implements Configuration.Provider {
public class App extends DaggerApplication implements Configuration.Provider {
private static final String TAG = "App";
public static int profileId = -1;
private Context mContext;
@ -181,6 +185,17 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
return Icon.createWithBitmap(bitmap);
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
MultiDex.install(this);
}
@Override
protected AndroidInjector<? extends DaggerApplication> applicationInjector() {
return DaggerAppComponent.factory().create(this);
}
@Override
public void onCreate() {
super.onCreate();
@ -543,6 +558,7 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
appConfig = new AppConfig(this);
}
}
public void saveConfig()
{
try {
@ -724,5 +740,4 @@ public class App extends androidx.multidex.MultiDexApplication implements Config
devMode = false;
}
}
}

View File

@ -9,7 +9,6 @@ import android.os.*
import android.view.Gravity
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu
import androidx.core.graphics.ColorUtils
import androidx.lifecycle.Observer
@ -26,6 +25,7 @@ import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.IProfile
import dagger.android.support.DaggerAppCompatActivity
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -78,7 +78,7 @@ import java.io.IOException
import java.util.*
import kotlin.math.roundToInt
class MainActivity : AppCompatActivity() {
class MainActivity : DaggerAppCompatActivity() {
companion object {
var useOldMessages = false
@ -340,7 +340,7 @@ class MainActivity : AppCompatActivity() {
if (!profileListEmpty) {
handleIntent(intent?.extras)
}
app.db.profileDao().getAllFull().observe(this, Observer { profiles ->
app.db.profileDao().allFull.observe(this, Observer { profiles ->
// TODO fix weird -1 profiles ???
profiles.removeAll { it.id < 0 }
drawer.setProfileList(profiles)
@ -357,7 +357,7 @@ class MainActivity : AppCompatActivity() {
if (app.profile != null)
setDrawerItems()
app.db.metadataDao().getUnreadCounts().observe(this, Observer { unreadCounters ->
app.db.metadataDao().unreadCounts.observe(this, Observer { unreadCounters ->
unreadCounters.map {
it.type = it.thingType
}

View File

@ -10,6 +10,8 @@ import androidx.room.TypeConverters;
import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase;
import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDate;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterDateInt;
import pl.szczodrzynski.edziennik.data.db.converters.ConverterJsonObject;
@ -74,6 +76,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.teams.Team;
import pl.szczodrzynski.edziennik.data.db.modules.teams.TeamDao;
import pl.szczodrzynski.edziennik.utils.models.Date;
@Singleton
@Database(entities = {
Grade.class,
//GradeCategory.class,
@ -114,33 +117,60 @@ import pl.szczodrzynski.edziennik.utils.models.Date;
public abstract class AppDb extends RoomDatabase {
public abstract GradeDao gradeDao();
//public abstract GradeCategoryDao gradeCategoryDao();
public abstract TeacherDao teacherDao();
public abstract TeacherAbsenceDao teacherAbsenceDao();
public abstract TeacherAbsenceTypeDao teacherAbsenceTypeDao();
public abstract SubjectDao subjectDao();
public abstract NoticeDao noticeDao();
public abstract LessonDao lessonDao();
public abstract LessonChangeDao lessonChangeDao();
public abstract TeamDao teamDao();
public abstract AttendanceDao attendanceDao();
public abstract EventDao eventDao();
public abstract EventTypeDao eventTypeDao();
public abstract LoginStoreDao loginStoreDao();
public abstract ProfileDao profileDao();
public abstract LuckyNumberDao luckyNumberDao();
public abstract AnnouncementDao announcementDao();
public abstract GradeCategoryDao gradeCategoryDao();
public abstract FeedbackMessageDao feedbackMessageDao();
public abstract MessageDao messageDao();
public abstract MessageRecipientDao messageRecipientDao();
public abstract DebugLogDao debugLogDao();
public abstract EndpointTimerDao endpointTimerDao();
public abstract LessonRangeDao lessonRangeDao();
public abstract NotificationDao notificationDao();
public abstract ClassroomDao classroomDao();
public abstract NoticeTypeDao noticeTypeDao();
public abstract AttendanceTypeDao attendanceTypeDao();
public abstract MetadataDao metadataDao();
private static volatile AppDb INSTANCE;

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.data.db
import android.content.Context
import dagger.Module
import dagger.Provides
import javax.inject.Singleton
@Module
internal class DatabaseModule {
@Singleton
@Provides
fun provideDatabase(context: Context) = AppDb.getDatabase(context)
@Singleton
@Provides
fun provideEventDao(database: AppDb) = database.eventDao()
@Singleton
@Provides
fun provideMetadataDao(database: AppDb) = database.metadataDao()
}

View File

@ -1,19 +1,22 @@
package pl.szczodrzynski.edziennik.data.db.modules.events;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import androidx.room.RawQuery;
import androidx.room.Transaction;
import androidx.annotation.NonNull;
import android.util.Log;
import androidx.sqlite.db.SimpleSQLiteQuery;
import androidx.sqlite.db.SupportSQLiteQuery;
import java.util.List;
import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.utils.models.Date;
import pl.szczodrzynski.edziennik.utils.models.Time;
@ -21,6 +24,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_HOMEWORK;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_LESSON_CHANGE;
@Singleton
@Dao
public abstract class EventDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
@ -34,26 +38,32 @@ public abstract class EventDao {
@Query("DELETE FROM events WHERE profileId = :profileId AND eventId = :id")
public abstract void remove(int profileId, long id);
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
public abstract void removeMetadata(int profileId, int thingType, long thingId);
@Transaction
public void remove(int profileId, int type, long id) {
remove(profileId, id);
removeMetadata(profileId, type == Event.TYPE_HOMEWORK ? TYPE_HOMEWORK : TYPE_EVENT, id);
}
@Transaction
public void remove(Event event) {
remove(event.profileId, event.type, event.id);
}
@Transaction
public void remove(int profileId, Event event) {
remove(profileId, event.type, event.id);
}
@Query("DELETE FROM events WHERE teamId = :teamId AND eventId = :id")
public abstract void removeByTeamId(long teamId, long id);
@RawQuery(observedEntities = {Event.class})
abstract LiveData<List<EventFull>> getAll(SupportSQLiteQuery query);
public LiveData<List<EventFull>> getAll(int profileId, String filter) {
String query = "SELECT \n" +
"*, \n" +
@ -71,24 +81,31 @@ public abstract class EventDao {
Log.d("DB", query);
return getAll(new SimpleSQLiteQuery(query));
}
public LiveData<List<EventFull>> getAll(int profileId) {
return getAll(profileId, "1");
}
public List<EventFull> getAllNow(int profileId) {
return getAllNow(profileId, "1");
}
public LiveData<List<EventFull>> getAllWhere(int profileId, String filter) {
return getAll(profileId, filter);
}
public LiveData<List<EventFull>> getAllByType(int profileId, int type, String filter) {
return getAll(profileId, "eventType = "+type+" AND "+filter);
}
public LiveData<List<EventFull>> getAllByDate(int profileId, @NonNull Date date) {
return getAll(profileId, "eventDate = '"+date.getStringY_m_d()+"'");
}
public List<EventFull> getAllByDateNow(int profileId, @NonNull Date date) {
return getAllNow(profileId, "eventDate = '"+date.getStringY_m_d()+"'");
}
public LiveData<List<EventFull>> getAllByDateTime(int profileId, @NonNull Date date, Time time) {
if (time == null)
return getAllByDate(profileId, date);
@ -97,6 +114,7 @@ public abstract class EventDao {
@RawQuery
abstract List<EventFull> getAllNow(SupportSQLiteQuery query);
public List<EventFull> getAllNow(int profileId, String filter) {
return getAllNow(new SimpleSQLiteQuery("SELECT \n" +
"*, \n" +
@ -112,6 +130,7 @@ public abstract class EventDao {
"WHERE events.profileId = "+profileId+" AND events.eventBlacklisted = 0 AND "+filter+"\n" +
"ORDER BY eventStartTime, addedDate ASC"));
}
public List<EventFull> getNotNotifiedNow(int profileId) {
return getAllNow(profileId, "notified = 0");
}

View File

@ -9,7 +9,8 @@ import androidx.room.Transaction;
import java.util.List;
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice;
import javax.inject.Singleton;
import pl.szczodrzynski.edziennik.data.db.modules.announcements.Announcement;
import pl.szczodrzynski.edziennik.data.db.modules.attendance.Attendance;
import pl.szczodrzynski.edziennik.data.db.modules.events.Event;
@ -17,6 +18,7 @@ import pl.szczodrzynski.edziennik.data.db.modules.grades.Grade;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonChange;
import pl.szczodrzynski.edziennik.data.db.modules.lessons.LessonFull;
import pl.szczodrzynski.edziennik.data.db.modules.messages.Message;
import pl.szczodrzynski.edziennik.data.db.modules.notices.Notice;
import pl.szczodrzynski.edziennik.utils.models.UnreadCounter;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_ANNOUNCEMENT;
@ -28,6 +30,7 @@ import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_MESSAGE;
import static pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata.TYPE_NOTICE;
@Singleton
@Dao
public abstract class MetadataDao {
@Insert(onConflict = OnConflictStrategy.IGNORE)
@ -43,7 +46,6 @@ public abstract class MetadataDao {
abstract void updateNotified(int profileId, int thingType, long thingId, boolean notified);
@Transaction
public void setSeen(List<Metadata> metadataList) {
for (Metadata metadata: metadataList) {
@ -152,7 +154,6 @@ public abstract class MetadataDao {
}
@Query("UPDATE metadata SET seen = :seen WHERE profileId = :profileId AND thingType = :thingType")
public abstract void setAllSeen(int profileId, int thingType, boolean seen);
@ -166,7 +167,6 @@ public abstract class MetadataDao {
public abstract void setAllNotified(int profileId, boolean notified);
@Query("SELECT count() FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND seen = 0")
public abstract LiveData<Integer> countUnseen(int profileId, int thingType);
@ -183,7 +183,6 @@ public abstract class MetadataDao {
public abstract LiveData<Integer> countUnseen();
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = :thingType AND thingId = :thingId")
public abstract void delete(int profileId, int thingType, long thingId);
@ -191,12 +190,10 @@ public abstract class MetadataDao {
public abstract void deleteAll(int profileId);
@Query("SELECT profileId, thingType, COUNT(thingId) AS count FROM metadata WHERE seen = 0 GROUP BY profileId, thingType")
public abstract LiveData<List<UnreadCounter>> getUnreadCounts();
@Query("DELETE FROM metadata WHERE profileId = :profileId AND thingType = "+TYPE_GRADE+" AND thingId NOT IN (SELECT gradeId FROM grades WHERE profileId = :profileId);")
public abstract void deleteUnusedGrades(int profileId);

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import dagger.Component
import dagger.android.AndroidInjector
import dagger.android.support.AndroidSupportInjectionModule
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.DatabaseModule
import javax.inject.Singleton
@Singleton
@Component(modules = [
AndroidSupportInjectionModule::class,
BindingModule::class,
AppModule::class,
DatabaseModule::class
])
interface AppComponent : AndroidInjector<App> {
@Component.Factory
interface Factory : AndroidInjector.Factory<App>
}

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import android.content.Context
import dagger.Module
import dagger.Provides
import pl.szczodrzynski.edziennik.App
import javax.inject.Singleton
@Module
internal class AppModule {
@Singleton
@Provides
fun provideContext(app: App): Context = app
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di
import dagger.Module
import dagger.android.ContributesAndroidInjector
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.di.scopes.PerActivity
import pl.szczodrzynski.edziennik.di.scopes.PerFragment
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkFragment
import pl.szczodrzynski.edziennik.ui.modules.homework.list.HomeworkListFragment
@Module
@Suppress("unused")
internal abstract class BindingModule {
/**
* ACTIVITIES
*/
@PerActivity
@ContributesAndroidInjector
abstract fun bindMainActivity(): MainActivity
/**
* FRAGMENTS
*/
@PerFragment
@ContributesAndroidInjector
abstract fun bindHomeworkFragment(): HomeworkFragment
@PerFragment
@ContributesAndroidInjector
abstract fun bindHomeworkListFragment(): HomeworkListFragment
}

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di.scopes
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerActivity

View File

@ -0,0 +1,11 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.di.scopes
import javax.inject.Scope
@Scope
@Retention(AnnotationRetention.RUNTIME)
annotation class PerFragment

View File

@ -0,0 +1,22 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.base
import android.widget.Toast
import dagger.android.support.DaggerFragment
abstract class BaseFragment<T : BasePresenter<out BaseView>> : DaggerFragment(), BaseView {
abstract var presenter: T
override fun showMessage(text: String) {
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show()
}
override fun onDestroy() {
super.onDestroy()
presenter.onDetachView()
}
}

View File

@ -0,0 +1,18 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.base
open class BasePresenter<T : BaseView> {
var view: T? = null
open fun onAttachView(view: T) {
this.view = view
}
open fun onDetachView() {
view = null
}
}

View File

@ -0,0 +1,10 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.base
interface BaseView {
fun showMessage(text: String)
}

View File

@ -1,132 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.homework;
import android.content.Context;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.os.AsyncTask;
import androidx.annotation.NonNull;
import androidx.cardview.widget.CardView;
import androidx.recyclerview.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.List;
import pl.szczodrzynski.edziennik.App;
import pl.szczodrzynski.edziennik.R;
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull;
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog;
import pl.szczodrzynski.edziennik.ui.modules.home.HomeFragment;
import pl.szczodrzynski.edziennik.utils.models.Date;
import static pl.szczodrzynski.edziennik.utils.Utils.bs;
public class HomeworkAdapter extends RecyclerView.Adapter<HomeworkAdapter.ViewHolder> {
private Context context;
private List<EventFull> homeworkList;
//getting the context and product list with constructor
public HomeworkAdapter(Context mCtx, List<EventFull> homeworkList) {
this.context = mCtx;
this.homeworkList = homeworkList;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//inflating and returning our view holder
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.row_homework_item, parent, false);
return new ViewHolder(view);
}
public static String dayDiffString(Context context, int dayDiff) {
if (dayDiff > 0) {
if (dayDiff == 1) {
return context.getString(R.string.tomorrow);
}
else if (dayDiff == 2) {
return context.getString(R.string.the_day_after);
}
return HomeFragment.plural(context, R.plurals.time_till_days, Math.abs(dayDiff));
}
else if (dayDiff < 0) {
if (dayDiff == -1) {
return context.getString(R.string.yesterday);
}
else if (dayDiff == -2) {
return context.getString(R.string.the_day_before);
}
return context.getString(R.string.ago_format, HomeFragment.plural(context, R.plurals.time_till_days, Math.abs(dayDiff)));
}
return context.getString(R.string.today);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
App app = (App) context.getApplicationContext();
EventFull homework = homeworkList.get(position);
int diffDays = Date.diffDays(homework.eventDate, Date.getToday());
holder.homeworkItemHomeworkDate.setText(app.getString(R.string.date_relative_format, homework.eventDate.getFormattedString(), dayDiffString(context, diffDays)));
holder.homeworkItemTopic.setText(homework.topic);
holder.homeworkItemSubjectTeacher.setText(context.getString(R.string.homework_subject_teacher_format, bs(homework.subjectLongName), bs(homework.teacherFullName)));
holder.homeworkItemTeamDate.setText(context.getString(R.string.homework_team_date_format, bs(homework.teamName), Date.fromMillis(homework.addedDate).getFormattedStringShort()));
if (!homework.seen) {
holder.homeworkItemTopic.setBackground(context.getResources().getDrawable(R.drawable.bg_rounded_8dp));
holder.homeworkItemTopic.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
homework.seen = true;
AsyncTask.execute(() -> {
app.db.metadataDao().setSeen(App.profileId, homework, true);
});
}
else {
holder.homeworkItemTopic.setBackground(null);
}
holder.homeworkItemEdit.setVisibility((homework.addedManually ? View.VISIBLE : View.GONE));
holder.homeworkItemEdit.setOnClickListener(v -> {
new EventManualDialog(context).show(app, homework, null, null, EventManualDialog.DIALOG_HOMEWORK);
});
if (homework.sharedBy == null) {
holder.homeworkItemSharedBy.setVisibility(View.GONE);
}
else if (homework.sharedByName != null) {
holder.homeworkItemSharedBy.setText(app.getString(R.string.event_shared_by_format, (homework.sharedBy.equals("self") ? app.getString(R.string.event_shared_by_self) : homework.sharedByName)));
}
}
@Override
public int getItemCount() {
return homeworkList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
CardView homeworkItemCard;
TextView homeworkItemTopic;
TextView homeworkItemHomeworkDate;
TextView homeworkItemSharedBy;
TextView homeworkItemSubjectTeacher;
TextView homeworkItemTeamDate;
Button homeworkItemEdit;
ViewHolder(View itemView) {
super(itemView);
homeworkItemCard = itemView.findViewById(R.id.homeworkItemCard);
homeworkItemTopic = itemView.findViewById(R.id.homeworkItemTopic);
homeworkItemHomeworkDate = itemView.findViewById(R.id.homeworkItemHomeworkDate);
homeworkItemSharedBy = itemView.findViewById(R.id.homeworkItemSharedBy);
homeworkItemSubjectTeacher = itemView.findViewById(R.id.homeworkItemSubjectTeacher);
homeworkItemTeamDate = itemView.findViewById(R.id.homeworkItemTeamDate);
homeworkItemEdit = itemView.findViewById(R.id.homeworkItemEdit);
}
}
}

View File

@ -1,84 +1,77 @@
package pl.szczodrzynski.edziennik.ui.modules.homework
import android.os.AsyncTask
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.mikepenz.iconics.typeface.library.community.material.CommunityMaterial
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.FragmentHomeworkBinding
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.ui.base.BaseFragment
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.ui.modules.homework.list.HomeworkListFragment
import pl.szczodrzynski.edziennik.ui.modules.messages.MessagesFragment
import pl.szczodrzynski.edziennik.utils.Themes
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetSeparatorItem
import javax.inject.Inject
class HomeworkFragment : Fragment() {
class HomeworkFragment : BaseFragment<HomeworkPresenter>(), HomeworkView {
companion object {
var pageSelection = 0
}
private lateinit var app: App
private lateinit var activity: MainActivity
private lateinit var b: FragmentHomeworkBinding
@Inject
override lateinit var presenter: HomeworkPresenter
@Inject
lateinit var app: App
override val markAsReadSuccessString: String
get() = getString(R.string.main_menu_mark_as_read_success)
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
presenter.onAttachView(this)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
if (context == null)
return null
app = activity.application as App
activity = (getActivity() as MainActivity)
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = FragmentHomeworkBinding.inflate(inflater)
b.refreshLayout.setParent(activity.swipeRefreshLayout)
return b.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
override fun initView() {
// TODO check if app, activity, b can be null
if (app.profile == null || !isAdded)
return
b.refreshLayout.setParent(activity.swipeRefreshLayout)
activity.bottomSheet.prependItems(
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc)
.withIcon(CommunityMaterial.Icon.cmd_calendar_plus)
.withOnClickListener(View.OnClickListener {
activity.bottomSheet.close()
EventManualDialog(activity).show(app, null, null, null, EventManualDialog.DIALOG_HOMEWORK)
}),
BottomSheetSeparatorItem(true),
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check)
.withOnClickListener(View.OnClickListener {
activity.bottomSheet.close()
AsyncTask.execute { app.db.metadataDao().setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true) }
Toast.makeText(activity, R.string.main_menu_mark_as_read_success, Toast.LENGTH_SHORT).show()
}))
.withTitle(R.string.menu_add_event)
.withDescription(R.string.menu_add_event_desc)
.withIcon(CommunityMaterial.Icon.cmd_calendar_plus)
.withOnClickListener(View.OnClickListener { presenter.onAddEventClick() }),
BottomSheetSeparatorItem(true),
BottomSheetPrimaryItem(true)
.withTitle(R.string.menu_mark_as_read)
.withIcon(CommunityMaterial.Icon.cmd_eye_check)
.withOnClickListener(View.OnClickListener { presenter.onMarkAsReadClick() }))
b.viewPager.adapter = MessagesFragment.Adapter(childFragmentManager).also { adapter ->
adapter.addFragment(HomeworkListFragment().also { fragment ->
fragment.arguments = Bundle().also { args ->
args.putInt("homeworkDate", HomeworkDate.CURRENT)
}
}, getString(R.string.homework_tab_current))
adapter.addFragment(HomeworkListFragment().also { fragment ->
fragment.arguments = Bundle().also { args ->
args.putInt("homeworkDate", HomeworkDate.PAST)
}
}, getString(R.string.homework_tab_past))
adapter.addFragment(HomeworkListFragment.newInstance(HomeworkDate.CURRENT), getString(R.string.homework_tab_current))
adapter.addFragment(HomeworkListFragment.newInstance(HomeworkDate.PAST), getString(R.string.homework_tab_past))
}
b.viewPager.currentItem = pageSelection
@ -86,9 +79,7 @@ class HomeworkFragment : Fragment() {
b.viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {}
override fun onPageSelected(position: Int) {
pageSelection = position
}
override fun onPageSelected(position: Int) = presenter.onPageSelected(position)
})
b.tabLayout.setupWithViewPager(b.viewPager)
@ -96,11 +87,21 @@ class HomeworkFragment : Fragment() {
activity.navView.bottomBar.fabEnable = true
activity.navView.bottomBar.fabExtendedText = getString(R.string.add)
activity.navView.bottomBar.fabIcon = CommunityMaterial.Icon2.cmd_plus
activity.navView.setFabOnClickListener(View.OnClickListener {
EventManualDialog(activity).show(app, null, null, null, EventManualDialog.DIALOG_HOMEWORK)
})
activity.navView.setFabOnClickListener(View.OnClickListener { presenter.onHomeworkAddFabClick() })
activity.gainAttention()
activity.gainAttentionFAB()
}
override fun setPageSelection(position: Int) {
pageSelection = position
}
override fun closeBottomSheet() {
activity.bottomSheet.close()
}
override fun showAddHomeworkDialog() {
EventManualDialog(activity).show(app, null, null, null, EventManualDialog.DIALOG_HOMEWORK)
}
}

View File

@ -1,77 +0,0 @@
package pl.szczodrzynski.edziennik.ui.modules.homework
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.databinding.HomeworkListBinding
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
import pl.szczodrzynski.edziennik.getInt
import pl.szczodrzynski.edziennik.utils.models.Date
import pl.szczodrzynski.edziennik.utils.Themes
class HomeworkListFragment : Fragment() {
private lateinit var app: App
private lateinit var activity: MainActivity
private lateinit var b: HomeworkListBinding
private var homeworkDate = HomeworkDate.CURRENT
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
if (context == null)
return null
app = activity.application as App
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = HomeworkListBinding.inflate(inflater)
return b.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
// TODO check if app, activity, b can be null
if (app.profile == null || !isAdded)
return
if (arguments != null) {
homeworkDate = arguments.getInt("homeworkDate", HomeworkDate.CURRENT)
}
val layoutManager = LinearLayoutManager(context)
layoutManager.reverseLayout = true
layoutManager.stackFromEnd = true
b.homeworkView.setHasFixedSize(true)
b.homeworkView.layoutManager = layoutManager
val filter = when(homeworkDate) {
HomeworkDate.CURRENT -> "eventDate > '" + Date.getToday().stringY_m_d + "'"
else -> "eventDate <= '" + Date.getToday().stringY_m_d + "'"
}
app.db.eventDao()
.getAllByType(App.profileId, Event.TYPE_HOMEWORK, filter)
.observe(this, Observer { homeworkList ->
if (app.profile == null || !isAdded) return@Observer
if (homeworkList != null && homeworkList.size > 0) {
val adapter = HomeworkAdapter(context, homeworkList)
b.homeworkView.adapter = adapter
b.homeworkView.visibility = View.VISIBLE
b.homeworkNoData.visibility = View.GONE
} else {
b.homeworkView.visibility = View.GONE
b.homeworkNoData.visibility = View.VISIBLE
}
})
}
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework
import android.os.AsyncTask
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.modules.metadata.Metadata
import pl.szczodrzynski.edziennik.data.db.modules.metadata.MetadataDao
import pl.szczodrzynski.edziennik.ui.base.BasePresenter
import javax.inject.Inject
class HomeworkPresenter @Inject constructor(
private val metadataDao: MetadataDao
) : BasePresenter<HomeworkView>() {
override fun onAttachView(view: HomeworkView) {
super.onAttachView(view)
view.initView()
}
fun onPageSelected(position: Int) {
view?.setPageSelection(position)
}
fun onAddEventClick() {
view?.apply {
closeBottomSheet()
showAddHomeworkDialog()
}
}
fun onMarkAsReadClick() {
view?.apply {
closeBottomSheet()
AsyncTask.execute {
metadataDao.setAllSeen(App.profileId, Metadata.TYPE_HOMEWORK, true)
}
showMessage(markAsReadSuccessString)
}
}
fun onHomeworkAddFabClick() {
view?.showAddHomeworkDialog()
}
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework
import pl.szczodrzynski.edziennik.ui.base.BaseView
interface HomeworkView : BaseView {
val markAsReadSuccessString: String
fun initView()
fun closeBottomSheet()
fun showAddHomeworkDialog()
fun setPageSelection(position: Int)
}

View File

@ -0,0 +1,111 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework.list
import android.content.res.Resources
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.Drawable
import android.os.AsyncTask
import android.view.LayoutInflater
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.recyclerview.widget.RecyclerView
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.data.db.modules.metadata.MetadataDao
import pl.szczodrzynski.edziennik.databinding.RowHomeworkItemBinding
import pl.szczodrzynski.edziennik.utils.Utils.bs
import pl.szczodrzynski.edziennik.utils.models.Date
import javax.inject.Inject
import kotlin.math.abs
class HomeworkListAdapter @Inject constructor(
private val metadataDao: MetadataDao
) : RecyclerView.Adapter<HomeworkListAdapter.ViewHolder>() {
val homeworkList: MutableList<EventFull> = mutableListOf()
lateinit var onItemEditClick: (homework: EventFull) -> Unit
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
val b: RowHomeworkItemBinding = DataBindingUtil.inflate(inflater, R.layout.row_homework_item, parent, false)
return ViewHolder(b)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val homework = homeworkList[position]
holder.apply {
val diffDaysString = dateDiffString(Date.diffDays(homework.eventDate, Date.getToday()))
b.homeworkItemHomeworkDate.text = getString(R.string.date_relative_format, homework.eventDate.formattedString, diffDaysString)
b.homeworkItemTopic.text = homework.topic
b.homeworkItemSubjectTeacher.text = getString(R.string.homework_subject_teacher_format, bs(homework.subjectLongName), bs(homework.teacherFullName))
b.homeworkItemTeamDate.text = getString(R.string.homework_team_date_format, bs(homework.teamName), Date.fromMillis(homework.addedDate).formattedStringShort)
when {
!homework.seen -> {
b.homeworkItemTopic.apply {
background = getDrawable(R.drawable.bg_rounded_8dp)
background.colorFilter = PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY)
}
homework.seen = true
AsyncTask.execute {
metadataDao.setSeen(App.profileId, homework, true)
}
}
else -> b.homeworkItemTopic.background = null
}
b.homeworkItemEdit.apply {
visibility = if (homework.addedManually) VISIBLE else GONE
setOnClickListener { onItemEditClick(homework) }
}
b.homeworkItemSharedBy.apply {
when {
homework.sharedBy == null -> visibility = GONE
homework.sharedByName != null -> text = getString(R.string.event_shared_by_format,
when (homework.sharedBy == "self") {
true -> getString(R.string.event_shared_by_self)
else -> homework.sharedByName
})
}
}
}
}
override fun getItemCount() = homeworkList.size
class ViewHolder(val b: RowHomeworkItemBinding) : RecyclerView.ViewHolder(b.root) {
fun getString(resId: Int): String = itemView.context.getString(resId)
fun getString(resId: Int, vararg formatArgs: Any): String = itemView.context.getString(resId, *formatArgs)
fun getDrawable(resId: Int): Drawable? = ContextCompat.getDrawable(itemView.context, resId)
val resources: Resources get() = itemView.context.resources
fun dateDiffString(diff: Int): String {
return when {
diff > 0 -> when (diff) {
1 -> getString(R.string.tomorrow)
2 -> getString(R.string.the_day_after)
else -> resources.getQuantityString(R.plurals.time_till_days, abs(diff), abs(diff))
}
diff < 0 -> when (diff) {
-1 -> getString(R.string.yesterday)
-2 -> getString(R.string.the_day_before)
else -> getString(R.string.ago_format, resources.getQuantityString(R.plurals.time_till_days, abs(diff), abs(diff)))
}
else -> getString(R.string.today)
}
}
}
}

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework.list
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.MainActivity
import pl.szczodrzynski.edziennik.R
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.databinding.HomeworkListBinding
import pl.szczodrzynski.edziennik.ui.base.BaseFragment
import pl.szczodrzynski.edziennik.ui.dialogs.event.EventManualDialog
import pl.szczodrzynski.edziennik.utils.Themes
import javax.inject.Inject
class HomeworkListFragment : BaseFragment<HomeworkListPresenter>(), HomeworkListView {
private lateinit var activity: MainActivity
private lateinit var b: HomeworkListBinding
@Inject
override lateinit var presenter: HomeworkListPresenter
@Inject
lateinit var app: App
@Inject
lateinit var homeworkAdapter: HomeworkListAdapter
override val viewLifecycle: Lifecycle
get() = lifecycle
companion object {
private const val ARGUMENT_KEY = "homeworkDate"
fun newInstance(homeworkDate: Int) = HomeworkListFragment().apply {
arguments = Bundle().apply { putInt(ARGUMENT_KEY, homeworkDate) }
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
presenter.onAttachView(this, arguments?.getInt(ARGUMENT_KEY))
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
activity = (getActivity() as MainActivity?) ?: return null
if (context == null)
return null
context!!.theme.applyStyle(Themes.appTheme, true)
if (app.profile == null)
return inflater.inflate(R.layout.fragment_loading, container, false)
// activity, context and profile is valid
b = HomeworkListBinding.inflate(inflater)
return b.root
}
override fun initView() {
// TODO check if app, activity, b can be null
if (app.profile == null || !isAdded)
return
val layoutManager = LinearLayoutManager(context).apply {
reverseLayout = true
stackFromEnd = true
}
homeworkAdapter.onItemEditClick = presenter::onItemEditClick
b.homeworkView.apply {
setHasFixedSize(true)
this.layoutManager = layoutManager
adapter = homeworkAdapter
}
}
override fun updateData(data: List<EventFull>) {
homeworkAdapter.apply {
homeworkList.apply {
clear()
addAll(data)
}
notifyDataSetChanged()
}
}
override fun showContent(show: Boolean) {
b.homeworkView.visibility = if (show) VISIBLE else GONE
}
override fun showNoData(show: Boolean) {
b.homeworkNoData.visibility = if (show) VISIBLE else GONE
}
override fun showEditHomeworkDialog(homework: EventFull) {
EventManualDialog(context).show(app, homework, null, null, EventManualDialog.DIALOG_HOMEWORK)
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework.list
import pl.szczodrzynski.edziennik.App
import pl.szczodrzynski.edziennik.data.db.modules.events.Event
import pl.szczodrzynski.edziennik.data.db.modules.events.EventDao
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.ui.base.BasePresenter
import pl.szczodrzynski.edziennik.ui.modules.homework.HomeworkDate
import pl.szczodrzynski.edziennik.utils.models.Date
import javax.inject.Inject
class HomeworkListPresenter @Inject constructor(
private val app: App,
private val eventDao: EventDao
) : BasePresenter<HomeworkListView>() {
fun onAttachView(view: HomeworkListView, homeworkDate: Int?) {
super.onAttachView(view)
view.initView()
loadData(homeworkDate ?: HomeworkDate.CURRENT)
}
private fun loadData(homeworkDate: Int) {
val today = Date.getToday().stringY_m_d
val filter = when (homeworkDate) {
HomeworkDate.CURRENT -> "eventDate > '$today'"
else -> "eventDate <= '$today'"
}
view?.run {
eventDao.getAllByType(App.profileId, Event.TYPE_HOMEWORK, filter)
.observe({ viewLifecycle }, { homeworkList ->
if (app.profile == null) return@observe
if (homeworkList != null && homeworkList.size > 0) {
updateData(homeworkList)
showContent(true)
showNoData(false)
} else {
showContent(false)
showNoData(true)
}
})
}
}
fun onItemEditClick(homework: EventFull) {
view?.showEditHomeworkDialog(homework)
}
}

View File

@ -0,0 +1,24 @@
/*
* Copyright (c) Kacper Ziubryniewicz 2019-11-4
*/
package pl.szczodrzynski.edziennik.ui.modules.homework.list
import androidx.lifecycle.Lifecycle
import pl.szczodrzynski.edziennik.data.db.modules.events.EventFull
import pl.szczodrzynski.edziennik.ui.base.BaseView
interface HomeworkListView : BaseView {
val viewLifecycle: Lifecycle
fun initView()
fun updateData(data: List<EventFull>)
fun showContent(show: Boolean)
fun showNoData(show: Boolean)
fun showEditHomeworkDialog(homework: EventFull)
}

View File

@ -1,113 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
xmlns:tools="http://schemas.android.com/tools">
<com.google.android.material.card.MaterialCardView
android:id="@+id/homeworkItemCard"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
app:cardElevation="4dp"
app:cardCornerRadius="5dp"
android:background="?selectableItemBackground"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="3dp">
android:orientation="vertical">
<LinearLayout
<com.google.android.material.card.MaterialCardView
android:id="@+id/homeworkItemCard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="8dp">
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:background="?selectableItemBackground"
android:paddingLeft="10dp"
android:paddingTop="5dp"
android:paddingRight="10dp"
android:paddingBottom="3dp"
app:cardCornerRadius="5dp"
app:cardElevation="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
android:orientation="vertical"
android:padding="8dp">
<TextView
android:id="@+id/homeworkItemHomeworkDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="16dp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="16sp"
tools:text="homeworkDate"
android:layout_marginEnd="16dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<com.mikepenz.iconics.view.IconicsTextView
android:id="@+id/homeworkItemSharedBy"
<TextView
android:id="@+id/homeworkItemHomeworkDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textSize="16sp"
tools:text="homeworkDate" />
<com.mikepenz.iconics.view.IconicsTextView
android:id="@+id/homeworkItemSharedBy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/constraintLayout"
app:layout_constraintTop_toBottomOf="@+id/eventListItemTopic"
tools:text="{cmd-share-variant} przez" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:ellipsize="end"
android:gravity="end"
android:maxLines="1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/constraintLayout"
app:layout_constraintTop_toBottomOf="@+id/eventListItemTopic"
tools:text="{cmd-share-variant} przez" />
</LinearLayout>
android:orientation="horizontal">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/homeworkItemTopic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:autoLink="all"
android:paddingBottom="4dp"
android:textIsSelectable="true"
android:textSize="18sp"
tools:text="topic???" />
<TextView
android:id="@+id/homeworkItemTopic"
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkItemEdit"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:minHeight="0dp"
android:text="@string/homework_edit"
android:visibility="visible" /><!--android:minWidth="0dp"
android:minHeight="0dp"-->
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="4dp"
android:textSize="18sp"
android:textIsSelectable="true"
android:autoLink="all"
tools:text="topic???" />
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/homeworkItemEdit"
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0"
android:minHeight="0dp"
android:text="@string/homework_edit"
android:visibility="visible" /><!--android:minWidth="0dp"
android:minHeight="0dp"-->
<TextView
android:id="@+id/homeworkItemSubjectTeacher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="subjectName, teacherName" />
<TextView
android:id="@+id/homeworkItemTeamDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="teamName addedDate" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/homeworkItemSubjectTeacher"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:layout_weight="1"
android:ellipsize="end"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="subjectName, teacherName" />
<TextView
android:id="@+id/homeworkItemTeamDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
tools:text="teamName addedDate" />
</LinearLayout>
</LinearLayout>
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
</LinearLayout>
</layout>

View File

@ -47,7 +47,8 @@ buildscript {
navlib : "e4ad01dc87",
gifdrawable : "1.2.15"
gifdrawable : "1.2.15",
dagger : "2.24"
]
}