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"/> | ||||