| var lessonPositionInList : Int = 0 | var lessonPositionInList : Int = 0 | ||||
| /** 该课时的总数据 或者作文关联的数据,如视频关联的内容*/ | /** 该课时的总数据 或者作文关联的数据,如视频关联的内容*/ | ||||
| var wordIds = mutableListOf<Long>() | var wordIds = mutableListOf<Long>() | ||||
| /** 学习进度位置,为已学下标的位置,在作文课堂练习时,初始值为0开始的下标,学习时已自动-1,取当前下标的值*/ | |||||
| /** 学习进度位置,为已学下标的位置,默认-1*/ | |||||
| var learnedIndex: Int = -1 | var learnedIndex: Int = -1 | ||||
| /**课时学前测试成绩 */ | /**课时学前测试成绩 */ | ||||
| var beforeTestScore = AppConstants.NOT_DOING | var beforeTestScore = AppConstants.NOT_DOING |
| import androidx.room.migration.Migration | import androidx.room.migration.Migration | ||||
| import androidx.sqlite.db.SupportSQLiteDatabase | import androidx.sqlite.db.SupportSQLiteDatabase | ||||
| import com.suliang.common.util.file.FileUtil | import com.suliang.common.util.file.FileUtil | ||||
| import com.xkl.cdl.data.bean.DictionaryBean | |||||
| import com.xkl.cdl.data.bean.DictionaryItem | import com.xkl.cdl.data.bean.DictionaryItem | ||||
| import com.xkl.cdl.module.XKLApplication | import com.xkl.cdl.module.XKLApplication | ||||
| import mqComsumerV1.Struct | import mqComsumerV1.Struct | ||||
| * create 2022/7/7 16:50 | * create 2022/7/7 16:50 | ||||
| * Describe: | * Describe: | ||||
| */ | */ | ||||
| @Database(entities = [Exam::class,ExamItem::class,DictionaryItem::class], version = 2, exportSchema = true) | |||||
| @Database(entities = [Exam::class,ExamItem::class,DictionaryItem::class,Collect::class], version = 3, exportSchema = true) | |||||
| abstract class AppDatabase : RoomDatabase() { | abstract class AppDatabase : RoomDatabase() { | ||||
| abstract fun examDao() : ExamDao | abstract fun examDao() : ExamDao | ||||
| abstract fun examItemDao(): ExamItemDao | abstract fun examItemDao(): ExamItemDao | ||||
| abstract fun examMiddleDao(): ExamMiddleDao | abstract fun examMiddleDao(): ExamMiddleDao | ||||
| abstract fun dictionaryDao(): DictionaryDao | abstract fun dictionaryDao(): DictionaryDao | ||||
| abstract fun c_CollectDao():C_CollectDao | |||||
| companion object{ | companion object{ | ||||
| private var DATABASE_NAME :String = "${FileUtil.getSaveDirPath("db")}${File.separator}app.db" | private var DATABASE_NAME :String = "${FileUtil.getSaveDirPath("db")}${File.separator}app.db" | ||||
| val MIGRATION_1_2 = object :Migration(1,2){ | |||||
| private val MIGRATION_1_2 = object :Migration(1,2){ | |||||
| override fun migrate(database : SupportSQLiteDatabase) { | override fun migrate(database : SupportSQLiteDatabase) { | ||||
| //版本升级策略,增加一个dictionary表 | //版本升级策略,增加一个dictionary表 | ||||
| database.execSQL("CREATE TABLE IF NOT EXISTS `dic_history` (`courseId` INTEGER NOT NULL, `queryTime` INTEGER NOT NULL, `id` INTEGER NOT NULL, `word` TEXT NOT NULL, `form` INTEGER NOT NULL, `pre_index` TEXT, `phonetic_uk` TEXT, `phonectic_us` TEXT, `phonectic_cn` TEXT, `basic_explaination` TEXT, `all_explaination` TEXT, `phrase` TEXT, `example` TEXT, `reference` TEXT, PRIMARY KEY(`word`))") | database.execSQL("CREATE TABLE IF NOT EXISTS `dic_history` (`courseId` INTEGER NOT NULL, `queryTime` INTEGER NOT NULL, `id` INTEGER NOT NULL, `word` TEXT NOT NULL, `form` INTEGER NOT NULL, `pre_index` TEXT, `phonetic_uk` TEXT, `phonectic_us` TEXT, `phonectic_cn` TEXT, `basic_explaination` TEXT, `all_explaination` TEXT, `phrase` TEXT, `example` TEXT, `reference` TEXT, PRIMARY KEY(`word`))") | ||||
| } | } | ||||
| } | } | ||||
| private val MIGRATION_2_3 = object :Migration(2,3){ | |||||
| override fun migrate(database : SupportSQLiteDatabase) { | |||||
| //版本升级策略,增加一个dictionary表 | |||||
| database.execSQL("CREATE TABLE IF NOT EXISTS `c_collect` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `courseId` INTEGER NOT NULL, `chapterId` INTEGER NOT NULL, `wordId` INTEGER NOT NULL, `lessonType` INTEGER NOT NULL)") | |||||
| } | |||||
| } | |||||
| val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { | val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { | ||||
| Room.databaseBuilder(XKLApplication.instance(), AppDatabase::class.java, DATABASE_NAME) | Room.databaseBuilder(XKLApplication.instance(), AppDatabase::class.java, DATABASE_NAME) | ||||
| .addMigrations(MIGRATION_1_2).build() | |||||
| .addMigrations(MIGRATION_1_2) | |||||
| .addMigrations(MIGRATION_2_3).build() | |||||
| } | } | ||||
| @JvmStatic | @JvmStatic |
| package com.xkl.cdl.data.exam_record | |||||
| import androidx.room.Dao | |||||
| import androidx.room.Insert | |||||
| import androidx.room.OnConflictStrategy | |||||
| import androidx.room.Query | |||||
| /** | |||||
| * author suliang | |||||
| * create 2022/8/12 15:02 | |||||
| * Describe: | |||||
| */ | |||||
| @Dao | |||||
| interface C_CollectDao { | |||||
| @Insert(onConflict = OnConflictStrategy.REPLACE) | |||||
| fun insert(item: Collect) : Long | |||||
| @Query("SELECT * FROM c_collect WHERE courseId = :courseId AND chapterId = :chapterId AND lessonType = :lessonType") | |||||
| fun queryAll(courseId:Long,chapterId:Long,lessonType:Int) : List<Collect> | |||||
| @Query("DELETE FROM c_collect WHERE id = :collectId") | |||||
| fun remove(collectId:Long) | |||||
| } |
| package com.xkl.cdl.data.exam_record | |||||
| import androidx.room.Entity | |||||
| import androidx.room.PrimaryKey | |||||
| /** | |||||
| * author suliang | |||||
| * create 2022/8/12 15:23 | |||||
| * Describe: | |||||
| */ | |||||
| @Entity(tableName = "c_collect") | |||||
| class Collect { | |||||
| @PrimaryKey(autoGenerate = true) | |||||
| var id : Long = 0 // 唯一键id 自动增长 | |||||
| var courseId : Long = 0 //课程 | |||||
| var chapterId : Long = 0 //章节 | |||||
| var wordId : Long = 0 //对应item的id | |||||
| var lessonType : Int = 0 //对应课时type类型 | |||||
| } |
| import net.sqlcipher.database.SQLiteDatabase | import net.sqlcipher.database.SQLiteDatabase | ||||
| import java.io.File | import java.io.File | ||||
| import java.util.* | import java.util.* | ||||
| import kotlin.math.abs | |||||
| /** | /** | ||||
| * author suliang | * author suliang | ||||
| AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> when (lesson.lessonType) { | AppConstants.COURSEPACK_TYPE_CHINESE_COMPOSITION -> when (lesson.lessonType) { | ||||
| //知识点 | //知识点 | ||||
| AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> { | AppConstants.LESSON_TYPE_COMPOSITION_KNOWLEDGE -> { | ||||
| lesson.learnedIndex = learnIndex | |||||
| // lesson.learnedIndex = learnIndex | |||||
| wordIds.size - 1 == learnIndex | wordIds.size - 1 == learnIndex | ||||
| } | } | ||||
| //视频 | //视频 | ||||
| } | } | ||||
| //课堂练习 | //课堂练习 | ||||
| AppConstants.LESSON_TYPE_COMPOSITION_READING -> { | AppConstants.LESSON_TYPE_COMPOSITION_READING -> { | ||||
| lesson.learnedIndex = learnIndex | |||||
| detail.lesson_learn_point[key]?.let { entityId -> | detail.lesson_learn_point[key]?.let { entityId -> | ||||
| lesson.learnedIndex = wordIds.indexOf(abs(entityId)) | |||||
| entityId < 0 //小于0 ,学习完成 | entityId < 0 //小于0 ,学习完成 | ||||
| } ?: false //否则未完成 | } ?: false //否则未完成 | ||||
| } | } |
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| import com.xkl.cdl.data.bean.course.CourseDetail | import com.xkl.cdl.data.bean.course.CourseDetail | ||||
| import com.xkl.cdl.data.bean.course.Lesson | import com.xkl.cdl.data.bean.course.Lesson | ||||
| import com.xkl.cdl.data.exam_record.AppDatabase | |||||
| import com.xkl.cdl.data.exam_record.Exam | |||||
| import com.xkl.cdl.data.exam_record.ExamItem | |||||
| import com.xkl.cdl.data.exam_record.ExamWithDetail | |||||
| import com.xkl.cdl.data.exam_record.* | |||||
| import com.xkl.cdl.data.manager.db.DBCourseManager | import com.xkl.cdl.data.manager.db.DBCourseManager | ||||
| import com.xkl.cdl.data.manager.db.DbControlBase | import com.xkl.cdl.data.manager.db.DbControlBase | ||||
| import com.xkl.cdl.module.XKLApplication | import com.xkl.cdl.module.XKLApplication | ||||
| import io.reactivex.rxjava3.annotations.NonNull | |||||
| import io.reactivex.rxjava3.core.Observable | import io.reactivex.rxjava3.core.Observable | ||||
| import mqComsumerV1.Struct | import mqComsumerV1.Struct | ||||
| import java.io.File | import java.io.File | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * 查询该课程该章节对应的视频板书收藏集合 | |||||
| * @param courseId Long | |||||
| * @param chapterId Long | |||||
| * @return Observable<List<Collect>> | |||||
| */ | |||||
| fun queryVideoBlackBoardCollect(courseId : Long,chapterId : Long): List<Collect>{ | |||||
| return queryCollect(courseId,chapterId,AppConstants.LESSON_TYPE_COMPOSITION_VIDEO) | |||||
| } | |||||
| /** | |||||
| * 获取该课程该章节的课堂练习的收藏集合 | |||||
| * @param courseId Long | |||||
| * @param chapterId Long | |||||
| * @return Observable<List<Collect>> | |||||
| */ | |||||
| fun queryCReadingCollect(courseId : Long,chapterId : Long): List<Collect>{ | |||||
| return queryCollect(courseId,chapterId,AppConstants.LESSON_TYPE_COMPOSITION_READING) | |||||
| } | |||||
| private fun queryCollect(courseId : Long,chapterId : Long,lessonType:Int): List<Collect>{ | |||||
| return AppDatabase.instance.c_CollectDao().queryAll(courseId,chapterId,lessonType) | |||||
| } | |||||
| /** | |||||
| * 添加视频板书到收藏 | |||||
| * @param courseId Long 课程id | |||||
| * @param chapterId Long 章节id | |||||
| * @param videoBlackboardId Long 版本id | |||||
| * @return Observable<Long> | |||||
| */ | |||||
| fun addVideoBlackBoardCollect(courseId : Long, chapterId : Long, videoBlackboardId : Long) : Observable<Long> { | |||||
| return Observable.fromCallable { | |||||
| AppDatabase.instance.c_CollectDao().insert(Collect().apply { | |||||
| this.courseId = courseId | |||||
| this.chapterId = chapterId | |||||
| this.wordId = videoBlackboardId | |||||
| this.lessonType = AppConstants.LESSON_TYPE_COMPOSITION_VIDEO | |||||
| }) | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 添加课堂练习到收藏 | |||||
| * @param courseId Long 课程id | |||||
| * @param chapterId Long 章节id | |||||
| * @param videoBlackboardId Long 版本id | |||||
| * @return Observable<Long> | |||||
| */ | |||||
| fun addCReadingCollect(courseId : Long, chapterId : Long, readingId : Long) : Observable<Long> { | |||||
| return Observable.fromCallable { | |||||
| AppDatabase.instance.c_CollectDao().insert(Collect().apply { | |||||
| this.courseId = courseId | |||||
| this.chapterId = chapterId | |||||
| this.wordId = readingId | |||||
| this.lessonType = AppConstants.LESSON_TYPE_COMPOSITION_READING | |||||
| }) | |||||
| } | |||||
| } | |||||
| /** | |||||
| * 移除收藏 | |||||
| * @param collectId Long 收藏的id | |||||
| */ | |||||
| fun removeCollect(collectId:Long) : Observable<Unit> { | |||||
| return Observable.fromCallable { | |||||
| AppDatabase.instance.c_CollectDao().remove(collectId) | |||||
| } | |||||
| } | |||||
| } | } |
| /** 显示答案 */ | /** 显示答案 */ | ||||
| private fun showAnswer() { | private fun showAnswer() { | ||||
| vm.isLearned = true | |||||
| vm.currentValue.value?.let { | vm.currentValue.value?.let { | ||||
| val builder = SpannableStringBuilder(it.answer) | val builder = SpannableStringBuilder(it.answer) | ||||
| if (vm.tipCount < vm.tipMaxForCurrent) { | if (vm.tipCount < vm.tipMaxForCurrent) { |
| /* 操作数据 */ | /* 操作数据 */ | ||||
| val learnData = DataTransferHolder.instance.getData<LearnData>() | val learnData = DataTransferHolder.instance.getData<LearnData>() | ||||
| //当前学习下标 初始为0 ,非-1 | |||||
| var currentLearnIndex = learnData.lesson.learnedIndex - 1 | |||||
| //当前学习下标 初始值为-1,不为-1,则显示当前内容,所以-1 | |||||
| var currentLearnIndex = learnData.lesson.learnedIndex.let { | |||||
| if (it != -1){ | |||||
| it - 1 | |||||
| }else it | |||||
| } | |||||
| //记录最后一条的item是否进行了学习, 初始标记直接为课时学习是否完成的标记就好了 | //记录最后一条的item是否进行了学习, 初始标记直接为课时学习是否完成的标记就好了 | ||||
| var lastIsLearned = learnData.lesson.learnIsOver | var lastIsLearned = learnData.lesson.learnIsOver | ||||
| //当前是否学习 | //当前是否学习 | ||||
| var isLearned = false | var isLearned = false | ||||
| */ | */ | ||||
| fun addCollect() : MutableLiveData<Long> { | fun addCollect() : MutableLiveData<Long> { | ||||
| val result = MutableLiveData<Long>() | val result = MutableLiveData<Long>() | ||||
| // TODO: 2022/5/19 实现收藏操作 | |||||
| Observable.create<Long> { | |||||
| currentValue.value?.collectId = 1 | |||||
| result.postValue(1) | |||||
| }.compose(diskIo2Main()).subscribe() | |||||
| currentValue.value?.let { item -> | |||||
| learnData.lesson.let { | |||||
| DataRepository.addCReadingCollect(it.courseId, it.chapterId, item.id) | |||||
| .compose(diskIo2Main()) | |||||
| .subscribe { collectId -> | |||||
| item.collectId = collectId | |||||
| result.postValue(collectId) | |||||
| } | |||||
| } | |||||
| } | |||||
| return result | return result | ||||
| } | } | ||||
| */ | */ | ||||
| fun removeCollect() : MutableLiveData<Long> { | fun removeCollect() : MutableLiveData<Long> { | ||||
| val result = MutableLiveData<Long>() | val result = MutableLiveData<Long>() | ||||
| // TODO: 2022/5/19 实现取消收藏操作 | |||||
| Observable.create<Long> { | |||||
| currentValue.value?.collectId = 0 | |||||
| result.postValue(0) | |||||
| }.compose(diskIo2Main()).subscribe() | |||||
| currentValue.value?.let { item -> | |||||
| learnData.lesson.let { | |||||
| DataRepository.removeCollect(item.collectId).compose(diskIo2Main()).subscribe { | |||||
| item.collectId = 0 | |||||
| result.postValue(0) | |||||
| } | |||||
| } | |||||
| } | |||||
| return result | return result | ||||
| } | } | ||||
| learnData.lesson.learnedIndex = currentLearnIndex | learnData.lesson.learnedIndex = currentLearnIndex | ||||
| val temp = learnData.lesson.learnIsOver == lastIsLearned | val temp = learnData.lesson.learnIsOver == lastIsLearned | ||||
| //发送信息,更改进度点 | //发送信息,更改进度点 | ||||
| if (!temp){ | |||||
| if (!temp) { | |||||
| //以前是未完成的,才进行发送操作 | //以前是未完成的,才进行发送操作 | ||||
| learnData.lesson.learnIsOver = true | learnData.lesson.learnIsOver = true | ||||
| } | } |
| layoutManager = LinearLayoutManager(this@LearnCVideoActivity, LinearLayoutManager.VERTICAL, false) | layoutManager = LinearLayoutManager(this@LearnCVideoActivity, LinearLayoutManager.VERTICAL, false) | ||||
| adapter = AdapterVideo(vm).apply { | adapter = AdapterVideo(vm).apply { | ||||
| onItemClick = { v, position, item -> | onItemClick = { v, position, item -> | ||||
| // TODO: 2022/5/25 点击事件,处理收藏和取消收藏 | |||||
| // when(item.collectId){ | |||||
| // 0L -> vm.addCollect(item).observe(this@LearnCVideoActivity){ | |||||
| // notifyDataSetChanged() | |||||
| // } | |||||
| // else -> vm.removeCollect(item).observe(this@LearnCVideoActivity){ | |||||
| // notifyDataSetChanged() | |||||
| // } | |||||
| // } | |||||
| when(item.collectId){ | |||||
| 0L -> vm.addCollect(item).observe(this@LearnCVideoActivity){ | |||||
| notifyDataSetChanged() | |||||
| } | |||||
| else -> vm.removeCollect(item).observe(this@LearnCVideoActivity){ | |||||
| notifyDataSetChanged() | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } |
| package com.xkl.cdl.module.learn | package com.xkl.cdl.module.learn | ||||
| import android.provider.SyncStateContract | |||||
| import androidx.lifecycle.LifecycleOwner | import androidx.lifecycle.LifecycleOwner | ||||
| import androidx.lifecycle.MutableLiveData | import androidx.lifecycle.MutableLiveData | ||||
| import appApi.AppApi | |||||
| import com.jeremyliao.liveeventbus.LiveEventBus | import com.jeremyliao.liveeventbus.LiveEventBus | ||||
| import com.suliang.common.extension.diskIo2Main | import com.suliang.common.extension.diskIo2Main | ||||
| import com.suliang.common.util.DateUtil | import com.suliang.common.util.DateUtil | ||||
| import com.suliang.common.util.LogUtil | import com.suliang.common.util.LogUtil | ||||
| import com.xkl.cdl.R | |||||
| import com.xkl.cdl.data.AppConstants | import com.xkl.cdl.data.AppConstants | ||||
| import com.xkl.cdl.data.DataTransferHolder | import com.xkl.cdl.data.DataTransferHolder | ||||
| import com.xkl.cdl.data.bean.VideoBean | import com.xkl.cdl.data.bean.VideoBean | ||||
| import com.xkl.cdl.data.bean.course.Lesson | import com.xkl.cdl.data.bean.course.Lesson | ||||
| import com.xkl.cdl.data.event.LearnEventData | import com.xkl.cdl.data.event.LearnEventData | ||||
| import com.xkl.cdl.data.manager.UserInfoManager | |||||
| import com.xkl.cdl.data.manager.db.DBCourseManager | import com.xkl.cdl.data.manager.db.DBCourseManager | ||||
| import com.xkl.cdl.data.manager.db.DbControlBase | import com.xkl.cdl.data.manager.db.DbControlBase | ||||
| import com.xkl.cdl.data.repository.DataRepository | import com.xkl.cdl.data.repository.DataRepository | ||||
| import io.reactivex.rxjava3.core.Observable | import io.reactivex.rxjava3.core.Observable | ||||
| import io.reactivex.rxjava3.functions.BiFunction | import io.reactivex.rxjava3.functions.BiFunction | ||||
| import mqComsumerV1.Struct | import mqComsumerV1.Struct | ||||
| import java.util.* | |||||
| import kotlin.Comparator | |||||
| import kotlin.collections.ArrayList | |||||
| class LearnCVideoViewModel : LearnBaseViewModel() { | class LearnCVideoViewModel : LearnBaseViewModel() { | ||||
| val lesson = DataTransferHolder.instance.getData<Lesson>() //视频课时lesson | val lesson = DataTransferHolder.instance.getData<Lesson>() //视频课时lesson | ||||
| var currentPlayTime : Long = lesson.videoPlayTime //当前播放时间: 毫秒 | |||||
| private val dbBaseControl : DbControlBase = DbControlBase(lesson.subjectId, lesson.coursePackId, lesson.coursePackType, lesson.courseId, lesson.courseType) | |||||
| var currentPlayTime : Long = lesson.videoPlayTime //当前播放时间: 毫秒 | |||||
| private val dbBaseControl : DbControlBase = DbControlBase(lesson.subjectId, lesson.coursePackId, lesson.coursePackType, | |||||
| lesson.courseId, lesson.courseType) | |||||
| var isCompletion = false //是否播放完成 | |||||
| var isLearn = false //是否有播放记录 | |||||
| var isCompletion = false //是否播放完成 | |||||
| var isLearn = false //是否有播放记录 | |||||
| var mVideoBean : VideoBean? = null //视频数据 | var mVideoBean : VideoBean? = null //视频数据 | ||||
| //选中tab 0:板书 1:笔记 | //选中tab 0:板书 1:笔记 | ||||
| var showTab = 0 | var showTab = 0 | ||||
| private var timeForLong : Long = 0 //本次学习开始的时间 | |||||
| private var timeForLong : Long = 0 //本次学习开始的时间 | |||||
| private var clientTag : String? = null | private var clientTag : String? = null | ||||
| //视频源 | //视频源 | ||||
| //我的笔记 | //我的笔记 | ||||
| var mCollectVideoBlackBoradList : MutableList<VideoBean.VideoBlackBoard> = ArrayList<VideoBean.VideoBlackBoard>() | |||||
| var mCollectVideoBlackBoradList : MutableList<VideoBean.VideoBlackBoard> = mutableListOf() | |||||
| //上传数据监听 | //上传数据监听 | ||||
| val uploadDate = MutableLiveData<Boolean>() | val uploadDate = MutableLiveData<Boolean>() | ||||
| /** 获取视频数据 */ | /** 获取视频数据 */ | ||||
| fun queryVideoData() : MutableLiveData<Boolean> { | fun queryVideoData() : MutableLiveData<Boolean> { | ||||
| val result = MutableLiveData<Boolean>() | val result = MutableLiveData<Boolean>() | ||||
| // TODO: 2022/5/24 获取该课时下的收藏信息 板书设置收藏id,同时对笔记进行排序 | |||||
| // io.reactivex.rxjava3.core.Observable.create<AppApi.CompCollectionDetailedResponse> { | |||||
| // val build = CompCollectionDetailedRequest.newBuilder().apply { | |||||
| // userId = 1 | |||||
| // productId = lesson.courseId | |||||
| // typeId = 2 | |||||
| // columnId = lesson.chapterId | |||||
| // }.build() | |||||
| // } | |||||
| Observable.create<Boolean> { | Observable.create<Boolean> { | ||||
| mVideoBean = DBCourseManager.queryVideoData(dbBaseControl,lesson) | |||||
| mVideoBean = DBCourseManager.queryVideoData(dbBaseControl, lesson) | |||||
| mVideoBean?.getmVideoBlackBoard()?.let { blackList -> | |||||
| DataRepository.queryVideoBlackBoardCollect(lesson.courseId, lesson.chapterId).forEach { c -> | |||||
| run m@ { | |||||
| blackList.forEach { | |||||
| if (it.videoBlackboardId == c.wordId){ | |||||
| it.collectId = c.id | |||||
| mCollectVideoBlackBoradList.add(it) | |||||
| return@m | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| mCollectVideoBlackBoradList.sortBy { | |||||
| it.sort | |||||
| } | |||||
| it.onNext(true) | it.onNext(true) | ||||
| it.onComplete() | it.onComplete() | ||||
| }.compose(diskIo2Main()) | |||||
| .subscribe{ | |||||
| }.compose(diskIo2Main()).subscribe { | |||||
| result.value = true | result.value = true | ||||
| } | } | ||||
| return result | return result | ||||
| } | } | ||||
| /* *//** 取消笔记 *//* | |||||
| fun removeCollect(item : VideoBean.VideoBlackBoard) : MutableLiveData<Boolean>? { | |||||
| /** 添加笔记 */ | |||||
| fun addCollect(item : VideoBean.VideoBlackBoard) : MutableLiveData<Boolean> { | |||||
| val result = MutableLiveData<Boolean>() | val result = MutableLiveData<Boolean>() | ||||
| //体验账号,当前页假数据 | |||||
| if (!UserInfoManager.getInstance().isOfficialAccount()) { | |||||
| item.setCollectId(0) | |||||
| mCollectVideoBlackBoradList.remove(item) | |||||
| result.postValue(true) | |||||
| return result | |||||
| } | |||||
| DataRepository.getInstance() | |||||
| .removeCollect(item.getCollectId()) | |||||
| .subscribe(object : BaseObserver<AppApi.CompRemoveCollectResponse?>(this) { | |||||
| fun onSuccess(data : AppApi.CompRemoveCollectResponse?) { | |||||
| item.setCollectId(0) | |||||
| mCollectVideoBlackBoradList.remove(item) | |||||
| result.postValue(true) | |||||
| } | |||||
| fun onFailed(code : Int, msg : String?) { | |||||
| getToast().setValue(XKLApplication.getInstance().getString(R.string.remove_collect_error)) | |||||
| DataRepository.addVideoBlackBoardCollect(lesson.courseId, lesson.chapterId, item.videoBlackboardId) | |||||
| .compose(diskIo2Main()) | |||||
| .subscribe { | |||||
| item.collectId = it | |||||
| var right = mCollectVideoBlackBoradList.size - 1 | |||||
| var left = 0 | |||||
| if (mCollectVideoBlackBoradList.isEmpty() || item.sort > mCollectVideoBlackBoradList[right].sort) { | |||||
| mCollectVideoBlackBoradList.add(item) | |||||
| } else if (item.sort < mCollectVideoBlackBoradList[left].sort) { | |||||
| mCollectVideoBlackBoradList.add(0, item) | |||||
| } else { | |||||
| //item应该在内部查找插入位置 | |||||
| var mid = 0 | |||||
| while(left <= right){ | |||||
| mid = left + (right - left) / 2 | |||||
| //寻找插入位置 | |||||
| if (item.sort < mCollectVideoBlackBoradList[mid].sort) { //小于,则在左边 | |||||
| right = mid - 1 | |||||
| } | |||||
| if (item.sort > mCollectVideoBlackBoradList[mid].sort) { //大于,则在右边 | |||||
| left = mid + 1 | |||||
| } | |||||
| } | |||||
| //循环完,找到的值 left将大于right,left的下标值,即为插入的位置 | |||||
| mCollectVideoBlackBoradList.add(left,item) | |||||
| } | } | ||||
| }) | |||||
| result.postValue(true) | |||||
| } | |||||
| return result | return result | ||||
| } | } | ||||
| *//** 添加笔记 *//* | |||||
| fun addCollect(item : VideoBean.VideoBlackBoard) : MutableLiveData<Boolean>? { | |||||
| /** 取消笔记 */ | |||||
| fun removeCollect(item : VideoBean.VideoBlackBoard) : MutableLiveData<Boolean> { | |||||
| val result = MutableLiveData<Boolean>() | val result = MutableLiveData<Boolean>() | ||||
| //体验账号,当前页假数据 | |||||
| if (!UserInfoManager.getInstance().isOfficialAccount()) { | |||||
| item.setCollectId(mCollectVideoBlackBoradList.size + 1) | |||||
| mCollectVideoBlackBoradList.add(item) | |||||
| result.postValue(true) | |||||
| return result | |||||
| } | |||||
| DataRepository.getInstance() | |||||
| .collect(getLesson().getCourseId(), getLesson().getChapterId(), item.getVideoBlackboardId(), | |||||
| SyncStateContract.Constants.COMPOSITON_COLLECT_VIDEO_BLACK_BOOK) | |||||
| .subscribe(object : BaseObserver<AppApi.CompCollectResponse?>(this) { | |||||
| fun onSuccess(data : AppApi.CompCollectResponse) { | |||||
| val collectedMap = data.collectedMap | |||||
| if (collectedMap != null) { | |||||
| val aLong = collectedMap[item.getVideoBlackboardId()] | |||||
| if (aLong != null) { | |||||
| item.setCollectId(aLong) | |||||
| mCollectVideoBlackBoradList.add(item) | |||||
| Collections.sort(mCollectVideoBlackBoradList, | |||||
| Comparator<Any?> { o1, o2 -> o1.getSort() - o2.getSort() }) | |||||
| } | |||||
| } | |||||
| result.postValue(true) | |||||
| } | |||||
| fun onFailed(code : Int, msg : String?) { | |||||
| getToast().setValue(XKLApplication.getInstance().getString(R.string.add_collect_error)) | |||||
| } | |||||
| }) | |||||
| DataRepository.removeCollect(item.collectId).compose(diskIo2Main()) | |||||
| .subscribe{ | |||||
| item.collectId = 0 | |||||
| mCollectVideoBlackBoradList.remove(item) | |||||
| result.value = true | |||||
| } | |||||
| return result | return result | ||||
| } | } | ||||
| */ | |||||
| //是否显示返回弹窗 | //是否显示返回弹窗 | ||||
| private var isShowBackDialog = false | private var isShowBackDialog = false | ||||
| override fun onResume(owner : LifecycleOwner) { | override fun onResume(owner : LifecycleOwner) { | ||||
| super.onResume(owner) | super.onResume(owner) | ||||
| if (!isShowBackDialog){ | |||||
| if (!isShowBackDialog) { | |||||
| startTotalCounting() | startTotalCounting() | ||||
| } | } | ||||
| } | } | ||||
| override fun onPause(owner : LifecycleOwner) { | override fun onPause(owner : LifecycleOwner) { | ||||
| super.onPause(owner) | super.onPause(owner) | ||||
| if (!isShowBackDialog){ | |||||
| if (!isShowBackDialog) { | |||||
| stopTotalCountTing() | stopTotalCountTing() | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * 显示或关闭的返回弹窗, 显示时关闭总计时 关闭时,开启总计时 | * 显示或关闭的返回弹窗, 显示时关闭总计时 关闭时,开启总计时 | ||||
| * @param isShow Boolean | * @param isShow Boolean | ||||
| */ | */ | ||||
| fun showOrDismissBackDialogForTime(isShow : Boolean) { | fun showOrDismissBackDialogForTime(isShow : Boolean) { | ||||
| isShowBackDialog = isShow | isShowBackDialog = isShow | ||||
| when{ | |||||
| when { | |||||
| isShowBackDialog -> stopTotalCountTing() | isShowBackDialog -> stopTotalCountTing() | ||||
| else -> startTotalCounting() | else -> startTotalCounting() | ||||
| } | } | ||||
| uploadDate.value = true | uploadDate.value = true | ||||
| return | return | ||||
| } | } | ||||
| Observable.zip( | |||||
| Observable.create<Boolean> { | |||||
| Observable.zip(Observable.create<Boolean> { | |||||
| try { | try { | ||||
| //保存视频播放时间 | //保存视频播放时间 | ||||
| XKLApplication.mobileCache.setVideoPoint(lesson.subjectId.toLong(), lesson.coursePackId, lesson.courseId, lesson.wordIds[0], currentPlayTime.toString()) | |||||
| XKLApplication.mobileCache.setVideoPoint(lesson.subjectId.toLong(), lesson.coursePackId, lesson.courseId, | |||||
| lesson.wordIds[0], currentPlayTime.toString()) | |||||
| it.onNext(true) | it.onNext(true) | ||||
| } catch (e : Exception) { | } catch (e : Exception) { | ||||
| e.printStackTrace() | e.printStackTrace() | ||||
| it.onNext(false) | it.onNext(false) | ||||
| } | } | ||||
| it.onComplete() | it.onComplete() | ||||
| }, | |||||
| Observable.create<Boolean> { emitter -> | |||||
| //保存数据 | |||||
| }, Observable.create<Boolean> { emitter -> | |||||
| //保存数据 | |||||
| val record = Struct.Record.newBuilder().apply { | val record = Struct.Record.newBuilder().apply { | ||||
| //进度点 | //进度点 | ||||
| addEntity(Struct.LearnEntity.newBuilder().apply { | addEntity(Struct.LearnEntity.newBuilder().apply { | ||||
| emitter.onNext(DataRepository.saveRecord(record)) | emitter.onNext(DataRepository.saveRecord(record)) | ||||
| emitter.onComplete() | emitter.onComplete() | ||||
| }, { t1, t2 -> | }, { t1, t2 -> | ||||
| t1 && t2 | |||||
| }).compose(diskIo2Main()).subscribe { | |||||
| if (!it){ | |||||
| t1 && t2 | |||||
| }).compose(diskIo2Main()).subscribe { | |||||
| if (!it) { | |||||
| LogUtil.e("视频数据保存有误") | LogUtil.e("视频数据保存有误") | ||||
| return@subscribe | return@subscribe | ||||
| } | } | ||||
| lesson.videoPlayTime = currentPlayTime | lesson.videoPlayTime = currentPlayTime | ||||
| LogUtil.e("当前播放时间:$currentPlayTime") | LogUtil.e("当前播放时间:$currentPlayTime") | ||||
| when{ | |||||
| when { | |||||
| //本课时已完成,只发送消息更新进度点即可 | //本课时已完成,只发送消息更新进度点即可 | ||||
| lesson.learnIsOver -> { | lesson.learnIsOver -> { | ||||
| //发送数据事件 | //发送数据事件 | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | ||||
| .post(LearnEventData(lesson.subjectId, lesson.courseId, | |||||
| AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| .post(LearnEventData(lesson.subjectId, lesson.courseId, AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| this.leesonPositionIndex = lesson.lessonPositionInList | this.leesonPositionIndex = lesson.lessonPositionInList | ||||
| isOnlyUpdatePoint = true | isOnlyUpdatePoint = true | ||||
| }) | }) | ||||
| lesson.learnIsOver = true | lesson.learnIsOver = true | ||||
| //发送数据事件 | //发送数据事件 | ||||
| LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | LiveEventBus.get<LearnEventData>(AppConstants.EVENT_LESSON_DATA) | ||||
| .post(LearnEventData(lesson.subjectId, lesson.courseId, | |||||
| AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| .post(LearnEventData(lesson.subjectId, lesson.courseId, AppConstants.DATA_LESSON_LEARN_OVER).apply { | |||||
| this.leesonPositionIndex = lesson.lessonPositionInList | this.leesonPositionIndex = lesson.lessonPositionInList | ||||
| isOnlyUpdatePoint = false | isOnlyUpdatePoint = false | ||||
| }) | }) | ||||
| } | } | ||||
| private fun getCurrentDateWithString() = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1) | private fun getCurrentDateWithString() = DateUtil.format(System.currentTimeMillis(), DateUtil.FORMAT_1) | ||||
| /* *//** | |||||
| /* */ | |||||
| /** | |||||
| * 上传学习时间 | * 上传学习时间 | ||||
| * 视频播放进度点 | * 视频播放进度点 | ||||
| *//* | *//* | ||||
| } | } | ||||
| *//** 发送动作返回进行统计 *//* | |||||
| */ | |||||
| /** 发送动作返回进行统计 *//* | |||||
| private fun dataToBack() { | private fun dataToBack() { | ||||
| //修改lesson学习数据 | //修改lesson学习数据 | ||||
| val learnLessson : CompositionLesson = getLesson() | val learnLessson : CompositionLesson = getLesson() | ||||
| } | } | ||||
| *//** | |||||
| */ | |||||
| /** | |||||
| * 保存当前的单词学习时长 | * 保存当前的单词学习时长 | ||||
| *//* | *//* | ||||
| private fun saveCurrentLearnDuration() : Struct.LearnDuration.Builder? { | private fun saveCurrentLearnDuration() : Struct.LearnDuration.Builder? { |
| */ | */ | ||||
| fun queryCompositionReadingData(entity : Lesson) : MutableLiveData<LearnData> { | fun queryCompositionReadingData(entity : Lesson) : MutableLiveData<LearnData> { | ||||
| val result = MutableLiveData<LearnData>() | val result = MutableLiveData<LearnData>() | ||||
| // TODO: 2022/5/19 查询课堂练习的收藏数据 需要给 CompositionReadingBean设置收藏id | |||||
| Observable.create<List<CompositionReadingBean>> { | Observable.create<List<CompositionReadingBean>> { | ||||
| result.postValue(LearnData(entity).apply { | result.postValue(LearnData(entity).apply { | ||||
| readingList = DBCourseManager.queryCompositionReading(dbControlBase, entity) | |||||
| readingList = DBCourseManager.queryCompositionReading(dbControlBase, entity).apply { | |||||
| DataRepository.queryCReadingCollect(entity.courseId,entity.chapterId).forEach { c -> | |||||
| run m@{ | |||||
| this.forEach { | |||||
| if (c.wordId == it.id){ | |||||
| it.collectId = c.id | |||||
| return@m | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| }) | }) | ||||
| it.onComplete() | it.onComplete() | ||||
| }.compose(diskIo2Main()).subscribe() | }.compose(diskIo2Main()).subscribe() |
| app:layout_constraintEnd_toEndOf="parent" | app:layout_constraintEnd_toEndOf="parent" | ||||
| app:layout_constraintStart_toStartOf="parent" | app:layout_constraintStart_toStartOf="parent" | ||||
| app:layout_constraintTop_toBottomOf="@+id/inc_statistics_number" | app:layout_constraintTop_toBottomOf="@+id/inc_statistics_number" | ||||
| android:paddingStart="8dp" | |||||
| android:paddingEnd="8dp" | |||||
| android:text="我的学习效果是?快去课时学后测试吧!" | android:text="我的学习效果是?快去课时学后测试吧!" | ||||
| android:visibility="gone"/> | android:visibility="gone"/> | ||||