From e8731dc5d1eee1a0bedabe10a467d7b450f266e5 Mon Sep 17 00:00:00 2001 From: niushuai233 Date: Tue, 5 Dec 2023 15:31:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20:rocket:=E5=88=9D=E7=89=88=E5=AE=8C?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 + .../1.json | 70 +++++++++++++ .../2.json | 70 +++++++++++++ app/src/main/AndroidManifest.xml | 4 +- .../cc/niushuai/didicheck/MainActivity.java | 9 +- .../didicheck/biz/dao/CheckRecordDao.java | 38 +++++++ .../didicheck/biz/entity/CheckRecord.java | 33 +++++- .../didicheck/biz/room/DBManager.java | 41 ++++++++ .../didicheck/biz/room/DiDiCheckDataBase.java | 13 +++ .../didicheck/ui/main/TabsPagerAdapter.java | 17 +++- .../didicheck/ui/main/home/HomeFragment.java | 96 ++++++++++++++---- .../ui/main/home/HomeRecycleViewAdapter.java | 49 ++++++++- app/src/main/res/mipmap-hdpi/ic_app.png | Bin 0 -> 2158 bytes app/src/main/res/mipmap-mdpi/ic_app.png | Bin 0 -> 1216 bytes app/src/main/res/mipmap-xhdpi/ic_app.png | Bin 0 -> 2587 bytes app/src/main/res/mipmap-xxhdpi/ic_app.png | Bin 0 -> 4336 bytes app/src/main/res/mipmap-xxxhdpi/ic_app.png | Bin 0 -> 6590 bytes icon/checkin.png | Bin 0 -> 4596 bytes 18 files changed, 412 insertions(+), 30 deletions(-) create mode 100644 app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/1.json create mode 100644 app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/2.json create mode 100644 app/src/main/java/cc/niushuai/didicheck/biz/dao/CheckRecordDao.java create mode 100644 app/src/main/java/cc/niushuai/didicheck/biz/room/DBManager.java create mode 100644 app/src/main/java/cc/niushuai/didicheck/biz/room/DiDiCheckDataBase.java create mode 100644 app/src/main/res/mipmap-hdpi/ic_app.png create mode 100644 app/src/main/res/mipmap-mdpi/ic_app.png create mode 100644 app/src/main/res/mipmap-xhdpi/ic_app.png create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_app.png create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_app.png create mode 100644 icon/checkin.png diff --git a/app/build.gradle b/app/build.gradle index 735ad02..61eff9d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,6 +62,8 @@ dependencies { def room_version = '2.6.1' implementation "androidx.room:room-runtime:$room_version" annotationProcessor "androidx.room:room-compiler:$room_version" + implementation "androidx.room:room-rxjava2:$room_version" + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' // room分页组件 implementation "androidx.room:room-paging:$room_version" } \ No newline at end of file diff --git a/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/1.json b/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/1.json new file mode 100644 index 0000000..ad845e3 --- /dev/null +++ b/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/1.json @@ -0,0 +1,70 @@ +{ + "formatVersion": 1, + "database": { + "version": 1, + "identityHash": "2a46dc7add9af1cfb97918cdfe07c10d", + "entities": [ + { + "tableName": "t_check_record", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `check_type` TEXT, `name` TEXT, `check_date` INTEGER, `description` TEXT, `create_date` INTEGER, `deleted` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "checkType", + "columnName": "check_type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "checkDate", + "columnName": "check_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createDate", + "columnName": "create_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2a46dc7add9af1cfb97918cdfe07c10d')" + ] + } +} \ No newline at end of file diff --git a/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/2.json b/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/2.json new file mode 100644 index 0000000..3baaea6 --- /dev/null +++ b/app/schemas/cc.niushuai.didicheck.biz.room.DiDiCheckDataBase/2.json @@ -0,0 +1,70 @@ +{ + "formatVersion": 1, + "database": { + "version": 2, + "identityHash": "2a46dc7add9af1cfb97918cdfe07c10d", + "entities": [ + { + "tableName": "t_check_record", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER, `check_type` TEXT, `name` TEXT, `check_date` INTEGER, `description` TEXT, `create_date` INTEGER, `deleted` INTEGER, PRIMARY KEY(`id`))", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "checkType", + "columnName": "check_type", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "checkDate", + "columnName": "check_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "createDate", + "columnName": "create_date", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": false + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "id" + ] + }, + "indices": [], + "foreignKeys": [] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '2a46dc7add9af1cfb97918cdfe07c10d')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d369e49..f46e6a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,9 +6,9 @@ android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" - android:icon="@mipmap/ic_launcher" + android:icon="@mipmap/ic_app" android:label="@string/app_name" - android:roundIcon="@mipmap/ic_launcher_round" + android:roundIcon="@mipmap/ic_app" android:supportsRtl="true" android:theme="@style/Theme.DiDiCheck" tools:targetApi="31"> diff --git a/app/src/main/java/cc/niushuai/didicheck/MainActivity.java b/app/src/main/java/cc/niushuai/didicheck/MainActivity.java index ef39af2..f6af166 100644 --- a/app/src/main/java/cc/niushuai/didicheck/MainActivity.java +++ b/app/src/main/java/cc/niushuai/didicheck/MainActivity.java @@ -10,10 +10,10 @@ import androidx.viewpager.widget.ViewPager; import com.github.clans.fab.FloatingActionButton; import com.github.clans.fab.FloatingActionMenu; +import cc.niushuai.didicheck.biz.enums.CheckTypeEnum; +import cc.niushuai.didicheck.biz.room.DBManager; import cc.niushuai.didicheck.databinding.ActivityMainBinding; import cc.niushuai.didicheck.ui.main.TabsPagerAdapter; -import cc.niushuai.didicheck.util.Toasts; -import cn.hutool.core.date.DateUtil; public class MainActivity extends AppCompatActivity { @@ -25,6 +25,9 @@ public class MainActivity extends AppCompatActivity { context = this; super.onCreate(savedInstanceState); + // 初始化数据库 + DBManager.init(this); + binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); @@ -48,7 +51,7 @@ public class MainActivity extends AppCompatActivity { swimActionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Toasts.shortShow(context, DateUtil.now() + swimActionButton.getLabelText() + "打卡完成"); + tabsPagerAdapter.getHomeFragment().add2Top(CheckTypeEnum.QUICK_ADD, "游泳"); // 打卡完成 关闭动画 didiCheckMenu.close(true); } diff --git a/app/src/main/java/cc/niushuai/didicheck/biz/dao/CheckRecordDao.java b/app/src/main/java/cc/niushuai/didicheck/biz/dao/CheckRecordDao.java new file mode 100644 index 0000000..8611613 --- /dev/null +++ b/app/src/main/java/cc/niushuai/didicheck/biz/dao/CheckRecordDao.java @@ -0,0 +1,38 @@ +package cc.niushuai.didicheck.biz.dao; + +import androidx.room.Dao; +import androidx.room.Delete; +import androidx.room.Insert; +import androidx.room.Query; + +import java.util.List; + +import cc.niushuai.didicheck.biz.entity.CheckRecord; +import io.reactivex.Completable; +import io.reactivex.Flowable; + +@Dao +public interface CheckRecordDao { + + @Query("SELECT * FROM t_check_record") + Flowable> listAll(); + + + @Query("select * from t_check_record where deleted = 0 and check_date = :date") + Flowable> queryByDate(long date); + + @Query("select * from t_check_record where deleted = 0 and create_date >= :startDate and create_date <= :endDate ") + Flowable> queryByDate(long startDate, long endDate); + + + @Insert + Completable insertAll(CheckRecord... records); + + @Delete + void delete(CheckRecord record); + + @Delete + void delete(CheckRecord... records); + + +} diff --git a/app/src/main/java/cc/niushuai/didicheck/biz/entity/CheckRecord.java b/app/src/main/java/cc/niushuai/didicheck/biz/entity/CheckRecord.java index c672a32..a7631ca 100644 --- a/app/src/main/java/cc/niushuai/didicheck/biz/entity/CheckRecord.java +++ b/app/src/main/java/cc/niushuai/didicheck/biz/entity/CheckRecord.java @@ -1,16 +1,33 @@ package cc.niushuai.didicheck.biz.entity; -import java.util.Date; +import androidx.room.ColumnInfo; +import androidx.room.Entity; +import androidx.room.PrimaryKey; import cc.niushuai.didicheck.biz.enums.CheckTypeEnum; +@Entity(tableName = "t_check_record") public class CheckRecord { + @PrimaryKey private Long id; + + @ColumnInfo(name = "check_type") private CheckTypeEnum checkType; + + @ColumnInfo(name = "name") private String name; + + @ColumnInfo(name = "check_date") + private Long checkDate; + + @ColumnInfo(name = "description") private String description; - private Date createDate; + + @ColumnInfo(name = "create_date") + private Long createDate; + + @ColumnInfo(name = "deleted") private Integer deleted; public Long getId() { @@ -37,6 +54,14 @@ public class CheckRecord { this.name = name; } + public Long getCheckDate() { + return checkDate; + } + + public void setCheckDate(Long checkDate) { + this.checkDate = checkDate; + } + public String getDescription() { return description; } @@ -45,11 +70,11 @@ public class CheckRecord { this.description = description; } - public Date getCreateDate() { + public Long getCreateDate() { return createDate; } - public void setCreateDate(Date createDate) { + public void setCreateDate(Long createDate) { this.createDate = createDate; } diff --git a/app/src/main/java/cc/niushuai/didicheck/biz/room/DBManager.java b/app/src/main/java/cc/niushuai/didicheck/biz/room/DBManager.java new file mode 100644 index 0000000..3585c1c --- /dev/null +++ b/app/src/main/java/cc/niushuai/didicheck/biz/room/DBManager.java @@ -0,0 +1,41 @@ +package cc.niushuai.didicheck.biz.room; + +import android.content.Context; + +import androidx.room.Room; +import androidx.room.RoomDatabase; + +import cc.niushuai.didicheck.biz.dao.CheckRecordDao; + +public class DBManager { + + public static DBManager INSTANCE; + private Context context; + private DiDiCheckDataBase diDiCheckDataBase; + + + public DBManager(Context context) { + this.context = context; + } + + public static void init(Context context) { + INSTANCE = new DBManager(context); + } + + public static RoomDatabase buildDatabase(Context context, Class clazz, String dbName) { + RoomDatabase.Builder databaseBuilder = Room.databaseBuilder(context, clazz, dbName); + databaseBuilder.setJournalMode(RoomDatabase.JournalMode.AUTOMATIC); + return databaseBuilder.build(); + } + + public DiDiCheckDataBase getDiDiCheckDataBase() { + if (null == diDiCheckDataBase) { + diDiCheckDataBase = (DiDiCheckDataBase) buildDatabase(context, DiDiCheckDataBase.class, "didi_check"); + } + return diDiCheckDataBase; + } + + public CheckRecordDao checkRecordDao() { + return getDiDiCheckDataBase().checkRecordDao(); + } +} diff --git a/app/src/main/java/cc/niushuai/didicheck/biz/room/DiDiCheckDataBase.java b/app/src/main/java/cc/niushuai/didicheck/biz/room/DiDiCheckDataBase.java new file mode 100644 index 0000000..fe86d60 --- /dev/null +++ b/app/src/main/java/cc/niushuai/didicheck/biz/room/DiDiCheckDataBase.java @@ -0,0 +1,13 @@ +package cc.niushuai.didicheck.biz.room; + +import androidx.room.Database; +import androidx.room.RoomDatabase; + +import cc.niushuai.didicheck.biz.dao.CheckRecordDao; +import cc.niushuai.didicheck.biz.entity.CheckRecord; + +@Database(entities = {CheckRecord.class}, version = 2) +public abstract class DiDiCheckDataBase extends RoomDatabase { + + public abstract CheckRecordDao checkRecordDao(); +} diff --git a/app/src/main/java/cc/niushuai/didicheck/ui/main/TabsPagerAdapter.java b/app/src/main/java/cc/niushuai/didicheck/ui/main/TabsPagerAdapter.java index aedb8ab..3e1b705 100644 --- a/app/src/main/java/cc/niushuai/didicheck/ui/main/TabsPagerAdapter.java +++ b/app/src/main/java/cc/niushuai/didicheck/ui/main/TabsPagerAdapter.java @@ -22,6 +22,9 @@ public class TabsPagerAdapter extends FragmentPagerAdapter { private static final int[] TAB_TITLES = new int[]{R.string.tab_home, R.string.tab_records, R.string.tab_settings}; private final Context mContext; + private HomeFragment homeFragment; + private DataListFragment dataListFragment; + public TabsPagerAdapter(Context context, FragmentManager fm) { super(fm); mContext = context; @@ -30,9 +33,11 @@ public class TabsPagerAdapter extends FragmentPagerAdapter { @Override public Fragment getItem(int position) { if (position == 0) { - return new HomeFragment(); + homeFragment = new HomeFragment(); + return homeFragment; } else if (position == 1) { - return new DataListFragment(); + dataListFragment = new DataListFragment(); + return dataListFragment; } else if (position == 2) { return new DataListFragment(); } @@ -49,4 +54,12 @@ public class TabsPagerAdapter extends FragmentPagerAdapter { public int getCount() { return 3; } + + public HomeFragment getHomeFragment() { + return homeFragment; + } + + public DataListFragment getDataListFragment() { + return dataListFragment; + } } \ No newline at end of file diff --git a/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeFragment.java b/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeFragment.java index 01b8280..45adcf3 100644 --- a/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeFragment.java +++ b/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeFragment.java @@ -19,14 +19,24 @@ import androidx.recyclerview.widget.DividerItemDecoration; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import java.util.ArrayList; +import org.reactivestreams.Subscription; + +import java.util.Collections; import java.util.Date; import java.util.List; import cc.niushuai.didicheck.biz.entity.CheckRecord; import cc.niushuai.didicheck.biz.enums.CheckTypeEnum; +import cc.niushuai.didicheck.biz.room.DBManager; import cc.niushuai.didicheck.databinding.FragmentHomeBinding; +import cc.niushuai.didicheck.util.Toasts; +import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import io.reactivex.Flowable; +import io.reactivex.FlowableSubscriber; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.schedulers.Schedulers; public class HomeFragment extends Fragment { @@ -34,6 +44,8 @@ public class HomeFragment extends Fragment { private FragmentHomeBinding fragmentHomeBinding; + private HomeRecycleViewAdapter homeRecycleViewAdapter; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -46,6 +58,7 @@ public class HomeFragment extends Fragment { @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + Log.d("Home", "onCreateView"); fragmentHomeBinding = FragmentHomeBinding.inflate(inflater, container, false); ConstraintLayout rootLayout = fragmentHomeBinding.getRoot(); @@ -53,14 +66,25 @@ public class HomeFragment extends Fragment { homeTitleTextView.setGravity(Gravity.CENTER); homeViewModel.getTitle().observe(getViewLifecycleOwner(), value -> homeTitleTextView.setText(value)); homeTitleTextView.setText("未完待续..."); + homeViewModel.setSelectDate(new Date()); CalendarView homeMainCalendar = fragmentHomeBinding.homeMainCalendar; homeMainCalendar.setDate(DateUtil.date().getTime()); homeMainCalendar.setOnDateChangeListener((calendarView, year, month, day) -> { long date = calendarView.getDate(); - Log.d("tagxx", "tag = " + DateUtil.date(date).toDateStr() + ", ==>" + year + month + day); + String format = StrUtil.format("{}-{}-{}", year, month + 1, day); + Log.d("calendar_change", "tag = " + DateUtil.date(date).toDateStr() + ", ==>" + format); + + // 缓存选择的日期 + homeViewModel.setSelectDate(DateUtil.parseDate(format)); + + // 刷新数据 + refreshDataListByDate(format); }); + // 默认查一次今天的数据 + refreshDataListByDate(DateUtil.formatDate(new Date())); + RecyclerView homeDataZoneRecyclerView = fragmentHomeBinding.homeDataZoneRecyclerView; homeDataZoneRecyclerView.addItemDecoration(new DividerItemDecoration(this.getActivity(), DividerItemDecoration.VERTICAL)); DefaultItemAnimator itemAnimator = new DefaultItemAnimator(); @@ -68,33 +92,69 @@ public class HomeFragment extends Fragment { itemAnimator.setRemoveDuration(1000); homeDataZoneRecyclerView.setItemAnimator(itemAnimator); - List recordList = new ArrayList<>(); - for (int i = 0; i < 50; i++) { - CheckRecord record = new CheckRecord(); - record.setId(new Date().getTime()); - record.setCheckType(CheckTypeEnum.ADD); - record.setName("recordName" + i); - record.setDescription(null); - record.setDeleted(0); - record.setCreateDate(new Date()); - recordList.add(record); - } - - HomeRecycleViewAdapter homeRecycleViewAdapter = new HomeRecycleViewAdapter(this.getActivity(), recordList); - homeDataZoneRecyclerView.setAdapter(homeRecycleViewAdapter); - LinearLayoutManager layoutManager = new LinearLayoutManager(this.getActivity()); - homeDataZoneRecyclerView.setLayoutManager(layoutManager); + homeRecycleViewAdapter = new HomeRecycleViewAdapter(getActivity(), Collections.emptyList()); + fragmentHomeBinding.homeDataZoneRecyclerView.setAdapter(homeRecycleViewAdapter); + LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity()); + fragmentHomeBinding.homeDataZoneRecyclerView.setLayoutManager(layoutManager); return rootLayout; } @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { + Log.d("Home", "onViewCreated"); super.onViewCreated(view, savedInstanceState); } @Override public void onDestroy() { super.onDestroy(); + fragmentHomeBinding = null; + } + + private void refreshDataListByDate(String date) { + DateTime dateTime = DateUtil.parseDate(date); + + Flowable> flowable = DBManager.INSTANCE.checkRecordDao().queryByDate(dateTime.getTime()); + flowable.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()) + .subscribe(new FlowableSubscriber>() { + @Override + public void onSubscribe(Subscription s) { + // 3s超时 + s.request(1); + } + + @Override + public void onNext(List checkRecords) { + Log.d("onNext", "查询到 " + date + " 数据 " + checkRecords.size()); + RecyclerView recyclerView = fragmentHomeBinding.homeDataZoneRecyclerView; + int childCount = recyclerView.getChildCount(); + if (childCount > 0) { + recyclerView.removeAllViews(); + } + homeRecycleViewAdapter.resetRecordList(checkRecords); + } + + @Override + public void onError(Throwable t) { + Toasts.shortShow(getActivity(), "根据时间拉取历史数据失败: ", t.getLocalizedMessage()); + } + + @Override + public void onComplete() { + } + }); + + } + + public void add2Top(CheckTypeEnum checkType, String name) { + CheckRecord record = new CheckRecord(); + record.setId(System.currentTimeMillis()); + record.setName(name); + record.setCheckDate(homeViewModel.getSelectDate().getValue().getTime()); + record.setCheckType(checkType); + record.setDeleted(0); + record.setCreateDate(System.currentTimeMillis()); + homeRecycleViewAdapter.add2Top(record); } } diff --git a/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeRecycleViewAdapter.java b/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeRecycleViewAdapter.java index dae454e..2537458 100644 --- a/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeRecycleViewAdapter.java +++ b/app/src/main/java/cc/niushuai/didicheck/ui/main/home/HomeRecycleViewAdapter.java @@ -1,6 +1,7 @@ package cc.niushuai.didicheck.ui.main.home; import android.content.Context; +import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -8,11 +9,20 @@ import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; +import java.util.Date; import java.util.List; import cc.niushuai.didicheck.R; import cc.niushuai.didicheck.biz.entity.CheckRecord; +import cc.niushuai.didicheck.biz.room.DBManager; +import cc.niushuai.didicheck.util.Toasts; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; +import io.reactivex.Completable; +import io.reactivex.CompletableObserver; +import io.reactivex.android.schedulers.AndroidSchedulers; +import io.reactivex.disposables.Disposable; +import io.reactivex.schedulers.Schedulers; public class HomeRecycleViewAdapter extends RecyclerView.Adapter { @@ -21,6 +31,7 @@ public class HomeRecycleViewAdapter extends RecyclerView.Adapter checkRecordList) { this.context = context; + this.checkRecordList.clear(); this.checkRecordList.addAll(checkRecordList); } @@ -35,11 +46,47 @@ public class HomeRecycleViewAdapter extends RecyclerView.Adapter checkRecords) { + // 全部更新数据 + this.checkRecordList.clear(); + if (CollUtil.isNotEmpty(checkRecords)) { + this.checkRecordList.addAll(checkRecords); + } + notifyDataSetChanged(); + } } diff --git a/app/src/main/res/mipmap-hdpi/ic_app.png b/app/src/main/res/mipmap-hdpi/ic_app.png new file mode 100644 index 0000000000000000000000000000000000000000..f988c552b900d7367bfd222b8731b3a865c62ac5 GIT binary patch literal 2158 zcmV-!2$A=RP) ztD}Q|h&rQUopHQ%1Vm9(MjS^4ufd}z_4&PIH{HH8HEEJ|sr$`*vu*Or`+e`*ckVuu z$$$X^1`HT5V8DO@0|pLf1T#%0lEHr3chK?%1xN;GlboC&w{W7oDqjeUW+M_okwY5A z+vPhwW%J6tRBS5#;>zxT+4N5+rZ&tDG3TL!I!7PhCaK1&9mY_u~i-)`*&E-eSN3jMK zR$L+=*9n?8Oa_-h#~#M8@1X0#u4<$S7&wO7!7j3l>u!vmt4wAJZ!+SphXsb2@l*L4}x`#K0W%>sSv zzz&Vx7^ zkqGDjA6h?&@)wonb4!^Y?tXhHR~ z<*54618UirqyU2^q2Rq5gDz%c^bF`d8~j0|e<~Z36zB?7YY^QCvN3vwVbFize_~KD z)8bg{;l!rNe8tjYb$=EQ2ERdA^Oyx`0=6n2V3GI}F9z1qMI##)3xnDqt93z+MGVa6 z!Vl}iTNXk7g10x;u(7c)XbsA@&CiE93+c{1vf&lwPTnrJ4YC$QpXkN6H3)-b@TCpK zFyk5UPmMXhVqdq)EZ!9LXr(vk+@N3tWdh_i)W z_NlGlAa4&mVG8y*Mbp>RXTgkZns~~+1vYt_spg6!*&oCUT^kg7swm34z<<`0jwl7&;g~Mc?gf%j*ktZBS@|C&-s`-DjdbyeOYWzopNK%%c2| z@~$k>(m1=k+2UxhCbA%mg?=~4@A1#tYTB9=FHg0s%qtcHjePeRX%{a_Gq~_z92sxW zx_&MamfYg8-Ce|%(^vZ4{_~)FU%weNx1_19E&CHW5w0Ef;qBu}R_@mrM9tX4DFZlV zsqN;@nWHxBY#F-k7WVha@Y=#<8~pAX`sTHN3~J)mkhbhk6Xt`%-XXQc4@C^p7)9Ji z-$|C{y-HfMcSij#S>9}EA!A)9sOIR`pw{e9$UP(8ASJ@mZU&99K0p@dy%PGK{Y@&E zc7uFA-$WGpwVEKnH%Ey`giU!bhgy=S^e!^3=n=9y=l!UdRI&$yrm%HP3U0T1tXK0+ z?1qB-qeLV^+ESWxJ|GVaf0L{m`cc&Pspb-H9U0>~K4K7h#5lH&Ndbl0QRrK0f;rZP zw2T$$;-Z2Tq}p?gYEVa2RaH4#$E4tNI=Ra5QIb%SbA;LCv7C3Kgy@wQm(C-V-b&S= zy?(#Hn5|>d@OV58szKwOb>xoxwkRQbmfa3T;sGYhw5Ev>W`DJ^t1$$ zt?6!(pG+*9PG(ydk;U9vvLg2d^6-eQWcBd&e&B0lW$sJlHghZXh%!0Ver`yQ#vFo{ z|E$a9Dr4)CHYg@t5AOGN9dnD&he5H%Jr;NIxU}okpKVy literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_app.png b/app/src/main/res/mipmap-mdpi/ic_app.png new file mode 100644 index 0000000000000000000000000000000000000000..4d214a4c8eb0624988f1dccff21f8adc38584d2e GIT binary patch literal 1216 zcmV;x1V8(UP)m|it76ByzH31vM2Mv)ZF<`7i@0l&80Ld3$i0g0QSQcIc`@y$O z0r2q=cpf|j?$I=D2|`U1V;2f1oNocgK$gO*4S{vrZVK?~kK#Jc|7YXjQ~?-}p9P=) zfgiNDx7UbCOcm4M@E!054{(-0g;mYX%>iKwIcvR!=JD!_GO^aD-|G(bRLLn*C>RX7 z;qO7P8$Q1Q$9bF+t*x!KVlsIHP9BG|>m&fbM>;w>JgIhZ4Ol^{fYkdCQGqy{!7E(E zAZ|NT+vEjWsBrQNclHG>II)f7HI{J!e~7khkSEpwlT>3sv=O)nb2{BA+ARZ}AK;G0 zG5S%_o<#KNnOMAQ+-lr%psFTa#(H_my}+m!Z3IP8DiQMx#l}RJLiA0{W5KD$L*sR02Ga{*)6Fsnto zCD;No!zuaoPTDU-Ln>}f0kOmkN!5Gt3cUuNt8Pq4ViOa$oB%5Fkn}$JW~mWB>i2JQ ziS103Re)R7gC6yjfOy{oz3;JUeaSbx8`v}UQ0O#s#SNbEFE@Qg=!vCgz5%M7n^f!qF}YSm$}wkewcg2x-b4+;KD ziPEQHa=!bFP56I>Cx14dQiD)b0gD66KRe_aeJB@K-ZA(gPnJY{h3j?t9iIQ@#aF98 z-zc`9j88Uf?kk#rC+2svLlviU@<7EXTRC^H`O!im*!}hIvi+4O)7n~LpEOL#7fZnN zX#q0vJ=c%Pq!%b#*;>yC8*!aVYh#st(oj(Z43d*BWqn$JY@{c#ukr*tn8B70d*!{R zfD2Rp;KxGhAt$lma(2M=Q(BNxa>Kk{Q@{^mUY0>0G32B*qOl!wK1mBwDh}fbE($G8 z3cw)ti+NcF)!}e*oE$ClKf;D8zfTKR3O-lYZ;t+DIyeyX$_tT+&&tc>aFw!-?VkO0 zTEJqF2I$%PtxUrc=K{7nEN*l+NVt#+90tUAJWRUIpkN7?o{ zAF~(c?qEv-E6l`c^E^T)c49J91s!ay0sk@sB!gh2v~XL&O!Wy~0|zusn=K|$FhZfw zJUCBabiU(a=)6cwU@E)>{t6CY(ca}K!nDZ=I-zK4YLX#DZE0!o7fLMDdO9c;PP)beF&peEMa)qj-$g2POEh&D5Z!Yr~k8A=!*uW@3qe&3200A%?BkQJT z@30AIYimpA{@CsIEbbq^^U2v5l~QA4<28z+Ohm&L)YR0h$M@a%d;_07_*?^-!zG}! zw8Lzb)iqELmc2Vf?KV3#h5I7uB!CAVzO8^CZ^Ng9(96(IpheZy)eXF}&^8SVcwo`6 zd1%P1&_~b(h!OQdUEva7l{>vse`OT3ZqRaQyId$iC7lGo&->xS=Q_UeWgkMX^UhOV zUT!rFlcOT7wzl?KIKCVDk50pagaB*}mjH{bZl%kIB&T*P4@Z-vlK}X-iu$CZ3-I&T zNW=`2f7nb_(%|epN`H^1jnLCsG-^(`1XyM5PJBO0*9}?@?T03lH%-z{z>V&`Z!h=w0Z%P8+yBgU?&)>+ADL2$Bb{BH+|w9cO(GL$4y( zcf+Qxsi|p6%-Un`+DKJ38vb2@F}>f-ID+b0D$dJ7!-H+2%r zKfvcgR6?WZHi4v40s`?L)$^eDY1^PvXy4cAHVFsL6~UP|iF19>TPWk2A{j4JH31y| z(Ou^+oiCDh@}X)x-6oM-1qT*F|0RxnjNrSdaX2Kqx`HI2FFpxSkCFszqBh~+frgHe zcJ?AMk4DnT;zDI*r35G5BTk)$=2P2&z=_uEz`&sTd5@Qk)Gk^i*|R5bKNeZ*qBaA8 zcHOLmR(L1t>gvj=Z9>4#ZzIky9Im_gL`H1~!s7CdK|s3ELl5Kg06uTyWh1qV7K_s} z1;4!)`@oT)?#y?1%BamiG&eVAqm3JAo1urOZQS999d`UIaikZ)|0=bO2%M?%fLJTK zis`CYl3V_Wm0$d^RxHh>>mmW|yNRn=JR`~XS7LDbX*)YeGwiq1bF z2e$j~7>*M=48e&S?D*pVC;G5xP0}W$#F2(}E>nUlqBA%GZlH#71y#;uCHN0EKK$HA z?TiQ?W|iRoxjx6TFHyU=f*sBXaKPsTbO*IFBL21q{eQ&I^r>B3!4B`F3Ba;eYG*_+ z&rMT8&-@>uc5wwxe1j$cJ!2-dGa{(_r=q>50^5(y*G}!?ib#M+K++HiNHQV;L!hMO z;cUsF-NkPLD{yr>>H5JS5->cwcXGKssAGX3CXTjQoBeI2^a*D!!sE@e?NlW z7x+)8B&*-1wvi$d5E0%qv+S9QV80(6_)FIUw7cjQks=as1&WKkqa>%c5P|+EB=E9! z9`nF9Q{%U;q1#1@NWcIT7A_fWae7uE&}Vdlf7a^MmYe1FJi6UrFl+)O$I{6KF149g zEOcEYj2ov)=-ulO=!-hRzi5>`bN%;hw>jFcmwcBQb%JkK z_wwY>&7#3@2^dr2wMe1WN}t8yd5qdpBzyZUGI23zZHkB%Q!>?c;wt#H!L6h!jmgP4C^~mMq(z`M1_+ z^jv1om!}u6`;|@hkpFJ9bExCr@g*Z*xlQh5_2Zv9u`F-z1KTo>&7!{-4=pJ2E~#_Z zeVS4Us8#CN_slP{?HTVxt<9N7*!9IfqCH$!H;-M1#EvHIG;qu*Ew z;OfqPi#3)!9TMKKgT@L4q9?)sWk?XFKPx zP1y%S95#}+Vd9@#wtx;l|KKA6jZwTw$4-MD&}gctHRaXR+(Cx$#c7O3QIBMKssNJ@f2A@|zkJ8vAgocI&8yxr-Jqn)8-x=b#5ww2v zpV{;;%%Tb4cS+aM*d&TH%mq)ufy-|j;nmPg=k4rg*?$RXz;M=<%){)PCEsPW?z+I> z^XH*A@`v|mU=ju#s8agh0rCGs5=odpuARM*)f3W?;i#>dN7&+`@3RK?1ls%0U>J_+ z<<232G4Me}=bZ|3OBb;2oV_6p8ctd_`j2c**#k82T>Rm5FO5Y~z%Y~pXF}e)Q>)an zsTDV}C53C)#!>r+(K*6#450^D2PWJb%4ho8LE8rHNJ`}sj*5zkTsZVgCG>p?tj=A} zX1H$k4NFg$x3UeRUT2%L4q=EooI>jHm6)sYf59Fc`xu+$yaRp*ooof_V10ePoyH*P z_@5;2Rzlw$5u(QGNo-ohO(~3^|BMDLADVet;ckLK5)+5G)Mw4o^tCg%(|-U2;~`QeD7 z|K`M06hE&y3a!I%)0)&eKNj#rU}!49=cJncSC=hElK|KUTg z(!&)MZ%5`28^*R{Y%D7Ax>fYdD+xS~2qr4gXDOwnx?yHdd4@{%;LE@_I)6i;(0-jc zak;IZJ6d!LyRFxoQ#s|iS8Zo_d^x`P2^eF=7WMxyK7)?SSs!tVWu>+YZF{Pdipmz8 zNOjP(*S@q?n$FgE7E3j3ZuR!uqTW$O%I^#s?@TSCJ0V&C7F1V2?%@*NNP3?TvpjqL9bZP+OsdqlSemOe)YD0(l6Lz z{>*0OP>bBtaNw~Tx}Gw!enGIP^eP%o-Mev~Y%O`n!r9|6;uT~4(ov;W*5z$>ZXbYm zp0E)s-JmVZ^F)Sp0=#+{6k|#w^xZ4a9U{e9-K?shh#0a3m@x{6T40$O-(D*`F4@&I z%OyH@H5L5;GXE-j6JEIb-<}oUZtLzvqFMiF6l+MERiMlGsznNho}9Ak5?v? z&2)NZ26J$JX(uEkghiv#ZohKNou9hc7n!`K^<3QXpk zaRl-&GC5DGCVE&a>a(6*EGiDa)Zz>6Mf`dtHboXN^hi!Sz-8}Rk7scwxGw&l_`gOn zwG3fm479DlnblvgJ8m6o?eLks%Z0q2KYyt)J3n{jBwljY|d!{ z(N%Iiu}WiM^88>McvwG2Mju{6spu`~I(2LN?d!xGTd?aax|0^7$fd-c04uQ!?*=i!-50iAlMYt@IRR!#II-Y&ko>>5bWf))c5YGP z5K%M%u3K^A6a-BIINvmJZ3~Z=#hZ8P9HGn4cx3FuSRv<(Wa!FE%BHS9QhMhojnj*S zfs@w!%UJdczPT!O?$BUzIaqz|0D=Om^bG|X(~`t(jTVxVBFM5uD9!{9lQ#aDa*8>8 z+#r?#@IDWJ*|SFH+P2H`MgMYof8SG=5qKykq?h#r$Ezoim>X$N}p6D8L+!YSB?7TmnG>)(3Zr_d$M&!`! zSFEhfMhF}8ACBg`NzrZ~R%(!WbotUXn1C{&L@mH@A#*G{-Xw-}_?)0d=y95eMls!W z%j1aFw{RJwz9HI`Kk7wiuCG>eZ(DA*&b2Z<7Jf;0@`hHi`x{|Ts=J2?a-c0VVl?k8 zRW)g;(71H4s_VeZ1ZU{z!B-rK@3sGf-#bY32$n5=6VYfHkYB+k&vO=cvu^Rm`a1tx zq38KCc?MVNbgwE{otTm@`*2CePnQq8u_aMY+kZ*uNtv-?qjSZYYZeN;7{<&x%Z`&z zG<5QL@4|zSVn7}xkgBPvDFlB~vUq?xwI(~{Y#8b`tSjY{HJC414%03C+5f_K`~Xpu z6TKZHp~}76lVEoHpL_cx=Eocy9Cw|Q7HOs&Y70!x8Hzq9oh%#mvaw+int|lHHfM%} zH`ffuPrRX_TKkLXVy9~^1TL&Po&K?v{_co|daIcqD50>fu8!VeNRaI)4V|ysN)ZwA z*6meGzdmN2LvTWcJ;*2+uBP z4H;GVIF$0>^$_Lhmiu}T$H!!tT4r>ePgv>>l}pl2nQNXE&!G+5l+Qseh|>+o zOor{JKXotMP@8HjIw@mHb~P27$#ao1z@kX>r3BgKP1mKOviH3FecO*;|jWC z#ApBA{rxES7p`1RH15L38=2Wx>Wb$hbPBNQuH9@`ReH%)h+AS3c`t$HQc=E>-mJN% zRcCOLDS?ZDUllM{rA&Tcefzghy5YwsH;pEq!IM1$cF_duzTWXN-0WOEgaU(GwBqh4 zn_N_?AjURzSV>j`jnPvF1+gRf$d3kjkAFZRgf zR#6#nT@ppkN%2yemkILE7@IyiYeUSD`4$2fU#7Z;bfL;n8OTei_s9rKnLm@R@ejAV zPSSfb^dgYrGMs(Zqna?DG-^^4=F@|wO%;MI}NJ;dk?(PqKh`sf2+X7kQjBPC!NCnbH<1? zVVO{G%1qlIA26kSO?tXV(3=C?exY=L?lEF8@;*a-1*SYonY37Y9dK0UZV;ji2~2SG zUwLg1GY!!jd{29W2KbKu^d_Z(cHlK@{Wv;T$FEhyKlJ?_0a7G(=4Y&#&wn*rCDf6> zo-TZIRNdz{dNXfh91>q)kK=O7E`D}WpV#`-!?`y=oq`jdz%z?s_4f);YS)eb8zu;3 zs<>Wcl#+gZmX7KGuE3u`&-~V{wv{~totZ>x{qItDBY@fNGNGKL10n0jk)Iy&A5W3S zRnAF(u`L)>CoqM4eIM=-m^R#Oc;)G#b&{s=Q@SL@!bI6}3rm$|qzm3kWyH)s*)5VL z0-h!1&+AB1yRx>@VYY8&PN!diN;XBeM-vJS=+PTncn`tRz?k;k&!Sv%GNF3#G8%&> z{Y!V=I%}&2dMDzJ1$$P~DA!{NjglEA`OaeYe(A2OD6}K?JK?D;pPxc26@?CUo=YHv zdRNlLs^HU~-}(9z{Kdz#;nwoUM-*MMVVzb5VNbg_#zrN*I+AW!za>%I$QZ)CHwV4n zB5t2my^$Rr)Kc_I(EPEJS`6}|d=uu|2E9?K4@8y#BW+bTZ*WsASQu z94yg>c~%*dp{L~MNrv@(I?DZgxo?A(Y5W=Z%NQ|r2cHqKx-cNY33vK#Hou`DrRb?X zPasi6vwRV%?ccv#JPUmxUvxRrlz0&^^;MSv4w}GNG~_#;|Cyga#^O??4FV@f4!CVeRl3VNh45Pl) zyX^(55M%4E)Lhmy{j;D2wxP(n43U(cg`vx z4Djay;nwEYIY9;3OW$|R6z(hzcV1dj#oPK6pO;uWeY>3&&Lef ztC#9VQcGjnkkE>%uZojq@qcFdyHkZ!vNoJFVI}+yx70O7y5II`tiqn|gnMTd& z;zob$vRswVs01B-E+|}zwoVSnX=+@*r|AzWYXfkL zz^Lx)(i$6dIVJK1UL@VJrKg)sqA06N<@c)f-q#+X1k3wh(pWEz;}5hOP9aas+IGTY zSH*rf>)0Jnaz7gJ=p|1=xN-`8qHE6xuyrE*90~YNRXT3Rm32mkdN}tmv7diaacpv# z$W<#!-5SZ~HPP#}#5Wni8eNk-+42zc?qK+n7UA3kXwYZ3O!?Eqk=jz7~uBOMxPEtJ|Q?>VA8?J12KzbRloC_F~;kd_nid zcvcpbBUAD(_b}&mol0=#r43-O zX;cACEQN(IPNog8luYC}?d23r<~>eumFbC?H-4&p_=pWR)J+tYbP=+)K9aC83N{`d zRSQBZACFS`)bHmt{gUhZgV_?-;Cgxz{{T9D@1!;1?ew&Xbhu+GdN?`LGcAXg&(H!C zUYhhT?c6`C`QOwr0+rhzXC#@X)Czy-&&>K=sOF~&(!VdSVkqQ5VE5juQ0RubG*70I?{5G>Y*%(NL?@xa zM>UmA)0p=j;<%U2Zf?a?_1O#NyHpY;+L*5$4B~l)SQ#6YO5vacrX9OeH`#I7ga>vA zX-@K|1ssD=tQ zeV7X>c|`E@C&c(4-TJswrOJx9go@b&lP|_Kv&Oq)zx5Uqn!os0>64KMF0X|9V}BP- zcaY@B{keoWKe-Hj!6w>xeUsu;@bU!{X^buX|Gkw3o6c3$3CqBLJEJ%;oa+Rt!JSK! zJ;_7Ju;W7d7arsSkmW#S!r5<6pJ#)4C+LnyAIHnsV|_41zn&?)>3+kb(c`3;R4kFA z_p4|W#_64h#vG3mQw?mo)%pjX`X*F{W9{pAUC}zXe_#5=bMVsX*|ROQ_Z2NL-_;ps z^hlZm8m=(Mw^{ToFg(WdA>4_t;824gZNGjs1%FH%`4Wj`L7_S_JWshIbWI)9Pj#3p zALYmKVN({#2qEb$eBMzSkrQ}aq?x>Syi-C>Uq$}VngQ03Wl?$O|4Jw$rIB6RnkS;c zf-8$nagoM)<6Vfqm^CvN>+%`K>0@*kzYnx(Kl=EYD&jJW*IfC06;d&0-Z zmmscnf)@o-@bx|A2>}BNxqqKfUojB?L$tJl5tlv!SjBR&S4z>3#s68@eCaO0Gfk#Z zewbSZzlj#f`&qL2-1i|?5CVbNO3$|`842sftX5W5g6bwsZaVP_`H%c1!LqjIR;sq5 zL1GdTXEoK;hO1D0!T=->@bdF}Qp@D<6#(~g(nN}4Z|t9<-r1QMpy#VsZ$74ZVOQ@$ zur`iS+)}fLeC6C|bKtD?6rVrR|AK_yvS2GcA+h9^mu)BOQyRb!)CX3!O&KV%hH3W> zobe(Rok{LON$$cZz!TBQ!`mWHsma8Eh4^c`b}J)3RIimhq)M>Iv!fYyRd23YFS>9j z_mSRS64I3AJK3(-8yOOG(5+qorgyfgt~=vUIL@(3JiM6Smj5P2c-X_jg_*S)>{i)J3qUJud8SRu;=bJG6dl zHLW$)i*#7?fdJQIZ%8D}=F8+#yL+RTV{eW7S<^?73MlL%`<&P8<% ztns~&W1JZ`_i|}o}Voc~;*^9ZT#DjS*DrTioM(rrK@Pat|+vIR#j8g zu(KC0c9}F*V*RB4jl$}~SGQu<8YNHR!j+dype)BvI3NW@HTwe}Dmh$(9&U?F?MeSB zf7y`6YmU20Ln;6|V(A+0Ouwgci{0GN(2(~c=IGK!@K4J3Baa-F8^`<@Q}DL#Q%;J z+LI z=RVMT1|OrE&!2f?Z?}yHw;j{+lgdL8x+j&Tr4IhA0&_c{k{^gPR#d4USgRv1W}(y& zY^t^jL`s>3urUil7t1)afE=!>dgW5BYB3f0AZ2*Y2g&9QRpuVmq{eueMyayake=jz zP@M-H5ao%h<5!%Psgsv;l5fYr8gry%=G8phOMyOLKQ^@!u>aGv5JhFP0xdGMSHIF( zEgz%pNryZ?@`bY~huIPO>q4gED$}9q=ho34Oa8;khZHjY)+l=hICx zTO0?<5OMSwa`Z*f!YH%UFkd%8HGjho!Cn1DcWd@&otkVO%PnC?z5%#J6iV?(uqWck zx8{}~OE9nVpKaPPm!k*6xVpj3z*C~y5?j$rrhIj)z{W~=dipw9e+JHr^5Pf?#j#^g zzptNSM)O@?Vv!Df&EGehIE`oKMsn(HVhNR6h#4pSev(;zQ(qNp3|GHJ zmSls;k;*ufE4s?=?qQ&R@bnD7-%3L;4D=LrqPreTqjQq2eIEJQ((;5GP6RHc=s8o3 z21gejWRQ)UImC|zmW`DkgTwYZMmv-_dP?T??K zLi`)edCABo{0q|&YQ@tTEJ5G;zr+_araP`3Uqb=HfBarh0 z_s+XN<+<}wZi)jdH;R8xmMc3t@c|j33=OW8hwWRH+t@UY`S`|e&GQKUiwUT_`Gu68 z7&SPTW%?0oq3^?riODq`iuXx%=1s1`$3WFXVal89 zjimGr4{+O}DJUUC>j_Ld$eSmYgtI7uy-QlKHZ@7CypERDmy(E(k50-4V zGE&C)oI!7C4*;#=IGW0K-|uskAD?9I4F8;EcJHb5retiU)OmTh^+XjSPx zNAZ3m&kbBBo6QLA&bkT1NL6y&BgUhiB9ddHvzTJkeR`juSgcOqKxG9(y0e_)@>mkt zSqsIX?@NlDHX^wRn+Lfpo=jw>I6k4v*@(1uIULyVP#-?ny(!f`}7CLJ-hFq3Aq-G#+=vn<3Eq^w-$*&i7N$|6*#H=;2p5f7|PN z0!vUU{9~vrZ(tajpijy2=e5d?XWA0>e`LWOsqsp1h?atC3}z?%0{eR*tG&C&C|23o zL%b~R;}e*xLutv~hI@N&4ppDRIuQ9NCrCQ9{yd{be+C{)JAo6_sxT|GQ#s7mg8#2T z&bFB?R`zd_d`GRSqcGNV4U%pYddGXiej4lF1)smNgl&Ru^IQWs@5a|Gy;ixM`Oo$< z{e3+DLo#1gFR&4Xjvj|FVlw=&dm#sKWzWr%QXFjnP7;+(p=W1FC{gH`F9GuX8mQNS z0*N?AnN#aL&6>y}mBJzx(~by@EYN!8{O8#&ja8w za4V?oC@O!%MMWMx{?b#Mky?OgTKa_g!smM7b6L6*`7c#+2;>A$cR%UHk40)Yt>SW} z?#aqNI)?21M7H+7nm!bj%hCl6I6Y_vlX!DY|K{BH>QLV9{3n$#hb?m=_kUK=ubJwu zAMfY^PhKPfJS?qlt)p4wEDRT_r-I2gPRbbXnF&%+0t{a$#gj)^=zbFT0Ah|Eq1UfIu4!R8+Th3{EgZU-f_#rsWtURi0g7i7z%b+1TYxZ&8fWxYcTdNkMY*_=1 zlRv?`7YzpT8KG`$+7Tn{ko-6OoxlIQ5T_1j>r9%rsO9 zUucN%G1}Fr>&l(Z2CcvR@wgQd!%$}2e9y9ckk5p_Qc<}6gxJ{~`L0d9(MeqNbWEKn zOj^6QorZ^4PYq)4p1o5Le2gCueEjGlMZk&?tG9 z884bo7H59d^Fro%OXB^J^Su~&fh#jOOnsjLQ%x?)7$0K%&e7KbWY0)>3z3>{w`R61P+bHrLtmpC2;rX)`1oyQlp z{h{RMJuetvbdn#Kk$gC*OqvYn$g}NfMM}$ za*7$5YaqXAPD)BzIs>maMJQP%_J?uM^+0@KL7s2V1O6jYgAkG6vb?U@lZpPca=^Ot z4Za9Y#{<2_BD`*i#wu?k;~a@S^b$iXqw_&n4!Ptu{Cex23n*gLW(%4&cHs+pWsjq^N$ zRVl@s-nMnfh=l{)zdM*8+VYWjbX34n6e%K7<X)i%zBnh)CF0rRpbn~u7CD;&IhH5v;)89U z2=I%Fl_R}G+Cy?izN9V3)@ImqRDG_ktyL%zY7ri?l7V^^6LcEK8Qo%DJ$d|nxg)HP zYRzOq6TLl@bCbhk7~^4VWOQqioLXJh(jvi%i}{QgdTWxH^NTy4^K!RM{=IFE^@WBA zIKD+5{Zvb94BYdQ4M!2CrhINn?EJHj8=SY4zKv__6T9hBDDDZjb!uo}L~9 zYpIWVt9-%$RVl2Y`4_g(ZbQ0?6v2uPSGY3QKx2nBKmI?=ovHD)h=v2RN#C&E@DEH> z(hvg!10fDY5IUHC!<&eGpOZmPs%MY7UhDwuX}?(2<;k=sED4J&FJn3{g>Q^-;-G^HQc7dO)q zpxB}jq>?8PgpsiMFMSJF%2Zxc5N;chvc|Nv@F}-*+>yzB;cy*1?9Z z(?@G&yxJ@*v}zUHU;m&OcIE5XVZ9XKd}}>Dk*8GRB;VuZ z70fTQNLh15QWT#X{GC~ba7k1_bnxlhMcc04mu~++9?{H}H2NtxmN*L(j;4v#-{?;2 z2I^K@>O436>Bmg2u6iM$9)6*jSFb$e^qg64ydJhdNLf&O49;ip?GqAJ?+UD;0v!7l zklSRMg%S)UHi=|f`hlhn@njQA;%aLfNmqTR_bBKiifNtmM~dPXWsC$9hip=_#}#%< z7}XUHcqMwDvLl0HaVjq`CyKeKN+~q7n+PO=n>;!B9Gbh2DIJ`nnIuOAn{~AmbJF^J zns@naVQgXO37_%_Di;zLS(#l+sV|MMzOJ_fGHVe1jO@yT_4KK;Lsg|*xLRadB>P+# z4=-tu_JRe#>h5M7zaYAxg$k8gXca#g6Zc}f@$T~&@qqCEW6K}F;IxbsK^tc2x$o~~ O0O}BJm0Bg6$o~S0wV@&a literal 0 HcmV?d00001 diff --git a/icon/checkin.png b/icon/checkin.png new file mode 100644 index 0000000000000000000000000000000000000000..67be36fb67a0220181476217955d9d802c0f8ffa GIT binary patch literal 4596 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 F{STD5p0xk~ literal 0 HcmV?d00001