mirror of
https://github.com/szkolny-eu/szkolny-android.git
synced 2025-06-22 10:03:03 +02:00
[UI] New notifications view.
This commit is contained in:
@ -21,7 +21,10 @@ interface NotificationDao {
|
||||
@Query("DELETE FROM notifications WHERE profileId = :profileId")
|
||||
fun clear(profileId: Int)
|
||||
|
||||
@Query("SELECT * FROM notifications")
|
||||
@Query("DELETE FROM notifications")
|
||||
fun clearAll()
|
||||
|
||||
@Query("SELECT * FROM notifications ORDER BY addedDate DESC")
|
||||
fun getAll(): LiveData<List<Notification>>
|
||||
|
||||
@Query("SELECT * FROM notifications")
|
||||
|
@ -1,104 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.notifications;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffColorFilter;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date;
|
||||
import pl.szczodrzynski.edziennik.utils.models.Notification;
|
||||
|
||||
import static pl.szczodrzynski.edziennik.utils.Utils.d;
|
||||
|
||||
public class NotificationsAdapter extends RecyclerView.Adapter<NotificationsAdapter.ViewHolder> {
|
||||
private static final String TAG = "NotificationsAdapter";
|
||||
private Context context;
|
||||
private List<Notification> notificationList;
|
||||
|
||||
//getting the context and product list with constructor
|
||||
public NotificationsAdapter(Context mCtx, List<Notification> notificationList) {
|
||||
this.context = mCtx;
|
||||
this.notificationList = notificationList;
|
||||
}
|
||||
|
||||
@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_notifications_item, parent, false);
|
||||
return new ViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||
App app = (App) context.getApplicationContext();
|
||||
|
||||
Notification notification = notificationList.get(position);
|
||||
|
||||
holder.notificationsItemDate.setText(Date.fromMillis(notification.addedDate).getFormattedString());
|
||||
holder.notificationsItemText.setText(notification.text);
|
||||
holder.notificationsItemTitle.setText(notification.title);
|
||||
holder.notificationsItemType.setText(Notification.stringType(context, notification.type));
|
||||
|
||||
holder.notificationsItemCard.setOnClickListener((v -> {
|
||||
Intent intent = new Intent("android.intent.action.MAIN");
|
||||
notification.fillIntent(intent);
|
||||
|
||||
d(TAG, "notification with item "+notification.redirectFragmentId+" extras "+(intent.getExtras() == null ? "null" : intent.getExtras().toString()));
|
||||
|
||||
//Log.d(TAG, "Got date "+intent.getLongExtra("timetableDate", 0));
|
||||
|
||||
if (notification.profileId != -1 && notification.profileId != app.profile.getId() && context instanceof Activity) {
|
||||
Toast.makeText(app, app.getString(R.string.toast_changing_profile), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
app.sendBroadcast(intent);
|
||||
}));
|
||||
|
||||
if (!notification.seen) {
|
||||
holder.notificationsItemText.setBackground(context.getResources().getDrawable(R.drawable.bg_rounded_8dp));
|
||||
holder.notificationsItemText.getBackground().setColorFilter(new PorterDuffColorFilter(0x692196f3, PorterDuff.Mode.MULTIPLY));
|
||||
}
|
||||
else {
|
||||
holder.notificationsItemText.setBackground(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return notificationList.size();
|
||||
}
|
||||
|
||||
class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
CardView notificationsItemCard;
|
||||
TextView notificationsItemDate;
|
||||
TextView notificationsItemText;
|
||||
TextView notificationsItemTitle;
|
||||
TextView notificationsItemType;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
notificationsItemCard = itemView.findViewById(R.id.notificationsItemCard);
|
||||
notificationsItemDate = itemView.findViewById(R.id.notificationsItemDate);
|
||||
notificationsItemText = itemView.findViewById(R.id.notificationsItemText);
|
||||
notificationsItemTitle = itemView.findViewById(R.id.notificationsItemTitle);
|
||||
notificationsItemType = itemView.findViewById(R.id.notificationsItemType);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,72 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.notifications
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import pl.szczodrzynski.edziennik.*
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.notification.Notification
|
||||
import pl.szczodrzynski.edziennik.data.db.modules.notification.getNotificationTitle
|
||||
import pl.szczodrzynski.edziennik.utils.Utils.d
|
||||
import pl.szczodrzynski.edziennik.utils.models.Date
|
||||
|
||||
class NotificationsAdapter(
|
||||
private val context: Context
|
||||
) : RecyclerView.Adapter<NotificationsAdapter.ViewHolder>() {
|
||||
companion object {
|
||||
private const val TAG = "NotificationsAdapter"
|
||||
}
|
||||
|
||||
var items = listOf<Notification>()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val inflater = LayoutInflater.from(context)
|
||||
val view = inflater.inflate(R.layout.row_notifications_item, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val app = context.applicationContext as App
|
||||
|
||||
val notification = items[position]
|
||||
|
||||
val date = Date.fromMillis(notification.addedDate).formattedString
|
||||
val colorSecondary = android.R.attr.textColorSecondary.resolveAttr(context)
|
||||
|
||||
holder.title.text = notification.text
|
||||
holder.profileDate.text = listOf(
|
||||
notification.profileName ?: "",
|
||||
" • ",
|
||||
date.asColoredSpannable(colorSecondary)
|
||||
).concat()
|
||||
holder.type.text = context.getNotificationTitle(notification.type)
|
||||
|
||||
holder.root.onClick {
|
||||
val intent = Intent("android.intent.action.MAIN")
|
||||
notification.fillIntent(intent)
|
||||
|
||||
d(TAG, "notification with item " + notification.viewId + " extras " + if (intent.extras == null) "null" else intent.extras!!.toString())
|
||||
|
||||
//Log.d(TAG, "Got date "+intent.getLongExtra("timetableDate", 0));
|
||||
|
||||
if (notification.profileId != -1 && notification.profileId != app.profile.id && context is Activity) {
|
||||
Toast.makeText(app, app.getString(R.string.toast_changing_profile), Toast.LENGTH_LONG).show()
|
||||
}
|
||||
app.sendBroadcast(intent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = items.size
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var root = itemView
|
||||
var title: TextView = itemView.findViewById(R.id.title)
|
||||
var profileDate: TextView = itemView.findViewById(R.id.profileDate)
|
||||
var type: TextView = itemView.findViewById(R.id.type)
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package pl.szczodrzynski.edziennik.ui.modules.notifications;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.databinding.DataBindingUtil;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import pl.szczodrzynski.edziennik.App;
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
import pl.szczodrzynski.edziennik.databinding.FragmentNotificationsBinding;
|
||||
import pl.szczodrzynski.edziennik.utils.Themes;
|
||||
|
||||
public class NotificationsFragment extends Fragment {
|
||||
|
||||
private App app = null;
|
||||
private Activity activity = null;
|
||||
private FragmentNotificationsBinding b = null;
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
activity = getActivity();
|
||||
if (getActivity() == null || getContext() == null)
|
||||
return null;
|
||||
app = (App) activity.getApplication();
|
||||
getContext().getTheme().applyStyle(Themes.INSTANCE.getAppTheme(), true);
|
||||
if (app.profile == null)
|
||||
return inflater.inflate(R.layout.fragment_loading, container, false);
|
||||
// activity, context and profile is valid
|
||||
b = DataBindingUtil.inflate(inflater, R.layout.fragment_notifications, container, false);
|
||||
return b.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
if (app == null || app.profile == null || activity == null || b == null || !isAdded())
|
||||
return;
|
||||
|
||||
RecyclerView recyclerView = b.notificationsView;
|
||||
recyclerView.setHasFixedSize(true);
|
||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
|
||||
if (app.appConfig.notifications.size() > 0) {
|
||||
NotificationsAdapter adapter = new NotificationsAdapter(getContext(), app.appConfig.notifications);
|
||||
recyclerView.setAdapter(adapter);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
|
||||
//linearLayoutManager.setReverseLayout(true);
|
||||
//linearLayoutManager.setStackFromEnd(true);
|
||||
recyclerView.setLayoutManager(linearLayoutManager);
|
||||
b.notificationsNoData.setVisibility(View.GONE);
|
||||
}
|
||||
else {
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
b.notificationsNoData.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-22.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.ui.modules.notifications
|
||||
|
||||
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.lifecycle.Observer
|
||||
import androidx.recyclerview.widget.DividerItemDecoration.HORIZONTAL
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
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.FragmentNotificationsBinding
|
||||
import pl.szczodrzynski.edziennik.utils.SimpleDividerItemDecoration
|
||||
import pl.szczodrzynski.edziennik.utils.Themes
|
||||
import pl.szczodrzynski.navlib.bottomsheet.items.BottomSheetPrimaryItem
|
||||
|
||||
|
||||
class NotificationsFragment : Fragment() {
|
||||
private lateinit var app: App
|
||||
private lateinit var activity: MainActivity
|
||||
private lateinit var b: FragmentNotificationsBinding
|
||||
|
||||
private val adapter by lazy {
|
||||
NotificationsAdapter(activity)
|
||||
}
|
||||
|
||||
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 = FragmentNotificationsBinding.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
|
||||
|
||||
activity.bottomSheet.prependItems(
|
||||
BottomSheetPrimaryItem(true)
|
||||
.withTitle(R.string.menu_remove_notifications)
|
||||
.withIcon(CommunityMaterial.Icon.cmd_delete_sweep_outline)
|
||||
.withOnClickListener(View.OnClickListener {
|
||||
activity.bottomSheet.close()
|
||||
AsyncTask.execute { app.db.notificationDao().clearAll() }
|
||||
Toast.makeText(activity, R.string.menu_remove_notifications_success, Toast.LENGTH_SHORT).show()
|
||||
}))
|
||||
|
||||
app.db.notificationDao()
|
||||
.getAll()
|
||||
.observe(this, Observer { notifications ->
|
||||
if (app.profile == null || !isAdded) return@Observer
|
||||
|
||||
adapter.items = notifications
|
||||
if (b.notificationsView.adapter == null) {
|
||||
b.notificationsView.adapter = adapter
|
||||
b.notificationsView.apply {
|
||||
setHasFixedSize(true)
|
||||
layoutManager = LinearLayoutManager(context).apply {
|
||||
addItemDecoration(SimpleDividerItemDecoration(context))
|
||||
}
|
||||
}
|
||||
}
|
||||
adapter.notifyDataSetChanged()
|
||||
|
||||
if (notifications != null && notifications.isNotEmpty()) {
|
||||
b.notificationsView.visibility = View.VISIBLE
|
||||
b.notificationsNoData.visibility = View.GONE
|
||||
} else {
|
||||
b.notificationsView.visibility = View.GONE
|
||||
b.notificationsNoData.visibility = View.VISIBLE
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) Kuba Szczodrzyński 2019-11-22.
|
||||
*/
|
||||
|
||||
package pl.szczodrzynski.edziennik.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import pl.szczodrzynski.edziennik.R;
|
||||
|
||||
public class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
|
||||
private Drawable mDivider;
|
||||
|
||||
public SimpleDividerItemDecoration(Context context) {
|
||||
mDivider = context.getResources().getDrawable(R.drawable.divider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
|
||||
int left = parent.getPaddingLeft();
|
||||
int right = parent.getWidth() - parent.getPaddingRight();
|
||||
|
||||
int childCount = parent.getChildCount();
|
||||
for (int i = 0; i < childCount; i++) {
|
||||
View child = parent.getChildAt(i);
|
||||
|
||||
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
|
||||
|
||||
int top = child.getBottom() + params.bottomMargin;
|
||||
int bottom = top + mDivider.getIntrinsicHeight();
|
||||
|
||||
mDivider.setBounds(left, top, right, bottom);
|
||||
mDivider.draw(c);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user