CookDetailViewModel.kt 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. package com.develop.step.viewmodel
  2. import androidx.lifecycle.LiveData
  3. import androidx.lifecycle.MutableLiveData
  4. import androidx.lifecycle.scopeNetLife
  5. import com.blankj.utilcode.util.FileUtils
  6. import com.blankj.utilcode.util.GsonUtils
  7. import com.blankj.utilcode.util.ToastUtils
  8. import com.blankj.utilcode.util.ZipUtils
  9. import com.develop.base.ext.getSN
  10. import com.develop.base.ext.globalApp
  11. import com.develop.base.mvvm.BaseViewModel
  12. import com.develop.base.util.FileKit
  13. import com.develop.base.util.MMkvUtils
  14. import com.develop.base.util.ThreadUtils
  15. import com.develop.common.data_repo.FoodDataProvider
  16. import com.develop.common.data_repo.db.entity.DevAccessory
  17. import com.develop.common.data_repo.db.entity.DevRecipe
  18. import com.develop.common.data_repo.db.entity.DevRecipeCategory
  19. import com.develop.common.data_repo.db.entity.DevRecipeCookingStep
  20. import com.develop.common.data_repo.db.entity.DevRecipeFood
  21. import com.develop.common.data_repo.db.entity.DevRecipeNutrition
  22. import com.develop.common.data_repo.db.entity.DevRecipePortionSize
  23. import com.develop.common.data_repo.db.entity.UserOnLineRecipes
  24. import com.develop.common.data_repo.net.Api
  25. import com.develop.common.data_repo.net.model.response.RecipeDataConfig
  26. import com.develop.common.data_repo.net.model.response.RecipeDetailResult
  27. import com.develop.common.tag.CURRENT_LANGUAGE
  28. import com.develop.common.tag.CURRENT_USER_ID
  29. import com.develop.common.tuya_bean.RecipesBean
  30. import com.develop.common.utils.CommonUtils
  31. import com.develop.common.utils.Resource
  32. import com.develop.step.TuyaCookStepType
  33. import com.develop.step.ui.recipes_detail.model.CookDetailInfo
  34. import com.drake.net.Get
  35. import com.drake.net.component.Progress
  36. import com.drake.net.interfaces.ProgressListener
  37. import com.google.gson.Gson
  38. import java.io.File
  39. class CookDetailViewModel : BaseViewModel() {
  40. var sn = getSN()
  41. var recipeLiveData = MutableLiveData<CookDetailInfo>()
  42. private val errorLiveData = MutableLiveData<Int>()
  43. val starCountLiveData = MutableLiveData<Int>()
  44. val downloadResource = MutableLiveData<Resource<Int>>()
  45. var portionSizeLiveData = MutableLiveData<DevRecipePortionSize>()
  46. var addLikeLiveData = MutableLiveData<Boolean>()
  47. var deleteLikeLiveData = MutableLiveData<Boolean>()
  48. var stepLiveDataString = MutableLiveData<String>()
  49. var onfialLiveData = MutableLiveData<String>()
  50. var recipeNumber: String? = null
  51. private var mRecipeUrl: String? = null
  52. var tuyaRecipe = ""
  53. //是否线上菜谱
  54. var isRemote = false
  55. var isTuyaStep = false
  56. /**
  57. * 数据源: 食谱编号
  58. * 关联数据: [DevRecipe] 食谱基本数据
  59. * [DevRecipeAccessory] 食谱需要的配件
  60. * [DevAccessory] 单个配件数据
  61. * [DevRecipeFood] 食谱原料数据
  62. * [DevRecipeNutrition] 食谱营养数据
  63. * [DevRecipePortionSize] 食谱原料用量
  64. */
  65. fun queryRecipe(number: String, remote: Boolean, recipesEdition: String) {
  66. if (sn.startsWith("011")) {
  67. var lang = MMkvUtils.getString(CURRENT_LANGUAGE) ?: "en"
  68. var map = HashMap<String, Any>()
  69. map["lang"] = lang
  70. map["menuId"] = number
  71. var gson = Gson()
  72. var json = gson.toJson(map)
  73. CommonUtils.getTuyaBean<RecipesBean>("tuya.device.menu.get", "1.0",
  74. json, RecipesBean::class.java, object : CommonUtils.TuyaHttp<RecipesBean> {
  75. override fun bean(t: RecipesBean) {
  76. //处理涂鸦步骤
  77. isTuyaStep = true
  78. var devRecipeCookingStep = mutableListOf<DevRecipeCookingStep>()
  79. //步骤
  80. devRecipeCookingStep.addAll(getListStep(t.cookStepInfoVOList,number,lang))
  81. //食谱
  82. val detailInfo = getTuyaRecipes(t,number, lang)
  83. tuyaRecipe = GsonUtils.toJson(detailInfo.recipe)
  84. stepLiveDataString.postValue(GsonUtils.toJson(devRecipeCookingStep))
  85. portionSizeLiveData.postValue(detailInfo.portionSize.firstOrNull())
  86. recipeLiveData.postValue(detailInfo)
  87. }
  88. override fun fail() {
  89. onfialLiveData.postValue("")
  90. }
  91. })
  92. } else {
  93. isRemote = remote
  94. this.recipeNumber = number
  95. if (remote) {
  96. scopeNetLife {
  97. Get<RecipeDetailResult>(Api.GET_RECIPES_DETAIL) {
  98. addQuery("recipeNumber", number)
  99. // addQuery("recipeEditon", recipesEdition)
  100. addQuery("lang", MMkvUtils.getString(CURRENT_LANGUAGE) ?: "EN")
  101. }.await().apply {
  102. mRecipeUrl = recipeUrl
  103. val detailInfo = CookDetailInfo(
  104. devRecipe,
  105. devAccessorys,
  106. devRecipeFoods,
  107. devRecipeNutritions,
  108. devRecipePortionSizes
  109. )
  110. portionSizeLiveData.postValue(detailInfo.portionSize.firstOrNull())
  111. recipeLiveData.postValue(detailInfo)
  112. }
  113. }.catch {
  114. ToastUtils.showShort(it.message)
  115. }
  116. if (FoodDataProvider.isResourceDownload(number)) {
  117. downloadResource.value = Resource(100, Resource.Status.SUCCESS)
  118. }
  119. } else {
  120. FoodDataProvider.getDatabase().runInTransaction {
  121. val recipeDao = FoodDataProvider.getDatabase().recipeDao()
  122. val recipeBean = recipeDao.queryRecipe(number)
  123. if (recipeBean == null) {
  124. // show toast
  125. errorLiveData.postValue(ERR_NO_RECIPE_MATCH)
  126. return@runInTransaction
  127. }
  128. val includeAccessory = mutableListOf<DevAccessory>()
  129. val accessoryIds = recipeDao.queryAccessoryIds(number)
  130. for (accessoryId in accessoryIds) {
  131. val accessory = recipeDao.queryAccessory(accessoryId.accessoryNumber ?: "")
  132. if (accessory != null) {
  133. includeAccessory.add(accessory)
  134. }
  135. }
  136. val includeMaterial = recipeDao.queryFood(number)
  137. val includeNutrition = recipeDao.queryNutrition(number)
  138. val includePortionSize = recipeDao.queryPortionSize(number)
  139. val detailInfo = CookDetailInfo(
  140. recipeBean,
  141. includeAccessory,
  142. includeMaterial,
  143. includeNutrition,
  144. includePortionSize
  145. )
  146. portionSizeLiveData.postValue(detailInfo.portionSize.firstOrNull())
  147. recipeLiveData.postValue(detailInfo)
  148. }
  149. }
  150. }
  151. }
  152. //涂鸦转换步骤
  153. fun getListStep(listStep: List<RecipesBean.CookStepInfoVOListBean>,number:String,langs: String) :MutableList<DevRecipeCookingStep> {
  154. var devStepList = mutableListOf<DevRecipeCookingStep>()
  155. listStep.forEach {
  156. //判断有没有 有cookArgs是模式 ,没有就是描述
  157. var code = it.menuId + it.id
  158. var wordMode = ""
  159. var makeMode = ""
  160. var direction = "0"
  161. var description = ""
  162. var autoStart = "manual"
  163. var minute = 0
  164. var second = 0
  165. var rotateSpeed = 0
  166. var temperature = 0
  167. var updateTime = 0L
  168. var createTime = 0L
  169. var lang = ""
  170. var audioFileCode = ""
  171. var audioFilePath = ""
  172. var photoVideoFileCode = ""
  173. var photoVideoFilePath = ""
  174. var numbers = ""
  175. if (it.cookArgs==null) {
  176. wordMode = "DESCRIPTION"
  177. } else {
  178. it.cookArgs.forEach { cookArgs ->
  179. when (cookArgs.dpCode) {
  180. TuyaCookStepType.DIRECTION -> {
  181. if (cookArgs.dpValue == "true") {
  182. direction = "0"
  183. } else {
  184. direction = "1"
  185. }
  186. }
  187. TuyaCookStepType.GEAR -> {
  188. rotateSpeed = cookArgs.dpValue.toInt()
  189. }
  190. TuyaCookStepType.TEMPERATURE -> {
  191. temperature = cookArgs.dpValue.toInt()
  192. }
  193. TuyaCookStepType.TIME -> {
  194. var time = cookArgs.dpValue.toInt()
  195. val minutes: Int = time / 60 // 计算分钟
  196. val seconds: Int = time % 60
  197. minute = minutes
  198. second = seconds
  199. }
  200. TuyaCookStepType.MODE -> {
  201. when (cookArgs.dpValue) {
  202. TuyaCookStepType.DP_DIY -> {
  203. wordMode = TuyaCookStepType.ADAPTED_COOKING
  204. }
  205. TuyaCookStepType.DP_KNEAD -> {
  206. wordMode = TuyaCookStepType.KNEAD_TOUGH
  207. }
  208. TuyaCookStepType.DP_STEAM -> {
  209. wordMode = TuyaCookStepType.STEAM
  210. }
  211. TuyaCookStepType.DP_BOIL_WATER -> {
  212. wordMode = TuyaCookStepType.BOIL_WATER
  213. }
  214. TuyaCookStepType.DP_SOUS_VIDE -> {
  215. wordMode = TuyaCookStepType.SOVS_VIDE
  216. }
  217. TuyaCookStepType.DP_RICE -> {
  218. wordMode = TuyaCookStepType.COOK_RICE
  219. }
  220. TuyaCookStepType.DP_CHOP -> {
  221. wordMode = TuyaCookStepType.CHOP
  222. }
  223. TuyaCookStepType.DP_PULSE -> {
  224. wordMode = TuyaCookStepType.TURBO
  225. }
  226. TuyaCookStepType.DP_SMOOTHIE -> {
  227. wordMode = TuyaCookStepType.SMOOTHIE
  228. }
  229. TuyaCookStepType.DP_AUTO_CLEAN -> {
  230. wordMode = TuyaCookStepType.AUTO_CLEAN
  231. }
  232. TuyaCookStepType.DP_WEIGHT -> {
  233. wordMode = TuyaCookStepType.WIGHT
  234. }
  235. TuyaCookStepType.DP_DICE -> {
  236. wordMode = TuyaCookStepType.DICING
  237. }
  238. TuyaCookStepType.DP_CITRUS_FRUITS -> {
  239. wordMode = TuyaCookStepType.CITRUS_JUICER
  240. }
  241. TuyaCookStepType.DP_PEELING -> {
  242. wordMode = TuyaCookStepType.POTATO_PEELER
  243. }
  244. TuyaCookStepType.DP_PREHEATING -> {
  245. wordMode = TuyaCookStepType.SPECIAL_DIY_MODE
  246. }
  247. TuyaCookStepType.DP_TNTERMITTENT_STIR -> {
  248. wordMode = TuyaCookStepType.BROWN
  249. }
  250. TuyaCookStepType.DP_WARNING -> {
  251. wordMode = TuyaCookStepType.WARNING
  252. }
  253. }
  254. }
  255. }
  256. }
  257. }
  258. numbers = it.step.toString()
  259. if (it.langInfos==null){
  260. description = ""
  261. lang = langs
  262. }else{
  263. it.langInfos.forEach { langInfosBean ->
  264. //由于客户涂鸦步骤没有文字,会打空格,估这里去除空格做判断
  265. if (langInfosBean.desc.trim() == ""){
  266. description = ""
  267. }else{
  268. description = langInfosBean.desc
  269. }
  270. lang = langInfosBean.lang
  271. }
  272. }
  273. /**
  274. * val code: String,
  275. * val recipeNumber: String?,
  276. * val number: String?,
  277. * val workMode: String?,
  278. * val photoVideoFileCode: String?,
  279. * val photoVideoFilePath: String?,
  280. * val audioFileCode: String?,
  281. * val audioFilePath: String?,
  282. * val makeMode: String?,
  283. * val autoStart: String?,
  284. * val temperature: Int?,
  285. * val rotateDirection: String?,
  286. * val rotateSpeed: Int?,
  287. * val minute: Int?,
  288. * val second: Int?,
  289. * val description: String?,
  290. * val lang: String?,
  291. * val updateTime: Long?,
  292. * val createTime: Long?
  293. *
  294. * **/
  295. var dev = DevRecipeCookingStep(
  296. code.toString(),
  297. number,
  298. numbers,
  299. wordMode,
  300. photoVideoFileCode,
  301. photoVideoFilePath,
  302. audioFileCode,
  303. audioFilePath,
  304. makeMode,
  305. autoStart,
  306. temperature,
  307. direction,
  308. rotateSpeed,
  309. minute,
  310. second,
  311. description,
  312. lang,
  313. updateTime,
  314. createTime
  315. )
  316. devStepList.add(dev)
  317. }
  318. return devStepList
  319. }
  320. //涂鸦转换食谱
  321. fun getTuyaRecipes(t: RecipesBean, number: String, lang: String): CookDetailInfo {
  322. var cookTime = t.cookTime
  323. var makeHours = cookTime / 3600;
  324. var makeMinutes = (cookTime % 3600) / 60;
  325. var userNum = t.pv ?: 0
  326. var desc = ""
  327. //步骤描述,食谱详情的第二个按钮
  328. if (t.menuStepInfoVOList!=null){
  329. val descBuilder = StringBuilder()
  330. t.menuStepInfoVOList.forEach {
  331. it.langInfos.let {itlang->
  332. itlang.forEach {langinfo->
  333. descBuilder.append(langinfo.desc)
  334. descBuilder.append("\n")
  335. }
  336. }
  337. }
  338. desc = descBuilder.toString()
  339. }
  340. var devRecipe = DevRecipe(
  341. t.id.toString(),
  342. t.id.toString(),
  343. "1.0",
  344. lang,
  345. "",
  346. t.mainImg,
  347. 0,
  348. 0,
  349. makeHours,
  350. makeMinutes,
  351. 0,
  352. 0,
  353. number,
  354. t.easyLevelDesc,
  355. "",
  356. t.name,
  357. desc,
  358. 0.0,
  359. userNum.toLong(),
  360. t.gmtModified,
  361. t.gmtCreate,
  362. "",
  363. ""
  364. )
  365. val includeAccessory = mutableListOf<DevAccessory>()
  366. var devRecipeFoodList = mutableListOf<DevRecipeFood>()
  367. var devRecipeNutritionList = mutableListOf<DevRecipeNutrition>()
  368. val includePortionSize = mutableListOf<DevRecipePortionSize>()
  369. //不add进去,那边会报错,直接随便新增一个
  370. includePortionSize.add(
  371. DevRecipePortionSize(
  372. "321654897",
  373. "2212zxc",
  374. "1542sqsc",
  375. "11wwss",
  376. lang,
  377. 1,
  378. 1
  379. )
  380. )
  381. var i = 1
  382. if (t.foodInfoVOList!=null){
  383. t.foodInfoVOList.forEach {
  384. var amout = 0.0
  385. var unit = ""
  386. if (it.menuFoodRelationVO.amount=="0"){
  387. amout = it.menuFoodRelationVO.secAmount.toDouble()
  388. if (it.menuFoodRelationVO.secUnitDesc==null){
  389. unit = "g"
  390. }else{
  391. unit = it.menuFoodRelationVO.secUnitDesc
  392. }
  393. }else{
  394. amout = it.menuFoodRelationVO.amount.toDouble()
  395. unit = "g"
  396. }
  397. devRecipeFoodList.add(
  398. DevRecipeFood(
  399. it.id.toString(),
  400. it.menuFoodRelationVO.foodId.toString(),
  401. amout,
  402. it.menuFoodRelationVO.menuId.toString(),
  403. lang,
  404. unit,
  405. it.name,
  406. "",
  407. it.gmtModified,
  408. it.gmtCreate
  409. )
  410. )
  411. it.foodNutritionVOList.forEach { food ->
  412. devRecipeNutritionList.add(
  413. DevRecipeNutrition(
  414. food.id.toString(),
  415. number,
  416. i.toString(),
  417. food.value.toDouble(),
  418. "g",
  419. "",
  420. lang,
  421. it.gmtModified,
  422. it.gmtCreate
  423. )
  424. )
  425. i++
  426. }
  427. }
  428. }
  429. return CookDetailInfo(
  430. devRecipe,
  431. includeAccessory,
  432. devRecipeFoodList,
  433. devRecipeNutritionList,
  434. includePortionSize
  435. )
  436. }
  437. fun addLikeRecipes(number: String) {
  438. var map = HashMap<String, Any>()
  439. map["menuId"] = number
  440. var gson = Gson()
  441. var json = gson.toJson(map)
  442. CommonUtils.getTuyaLike("tuya.device.menu.star.add", "1.0",
  443. json, object : CommonUtils.TuyaBooleanHttp {
  444. override fun bean(t: Boolean) {
  445. addLikeLiveData.postValue(t)
  446. }
  447. override fun fail() {
  448. onfialLiveData.postValue("")
  449. }
  450. })
  451. }
  452. fun deleteLikeRecipes(number: String) {
  453. var map = HashMap<String, Any>()
  454. map["menuId"] = number
  455. var gson = Gson()
  456. var json = gson.toJson(map)
  457. CommonUtils.getTuyaLike("tuya.device.menu.star.delete", "1.0",
  458. json, object : CommonUtils.TuyaBooleanHttp {
  459. override fun bean(t: Boolean) {
  460. deleteLikeLiveData.postValue(t)
  461. }
  462. override fun fail() {
  463. onfialLiveData.postValue("")
  464. }
  465. })
  466. }
  467. fun getRecipeLiveData(): LiveData<CookDetailInfo> {
  468. return recipeLiveData
  469. }
  470. fun getErrorCodeLiveData(): LiveData<Int> {
  471. return errorLiveData
  472. }
  473. fun getStarCount(recipesId: String) {
  474. FoodDataProvider.getUserDatabase().runInTransaction {
  475. val userTag = FoodDataProvider.getUserDatabase().userInfoDao().queryUserTag(
  476. CURRENT_USER_ID, recipesId
  477. )
  478. userTag?.apply {
  479. starCountLiveData.postValue(starCount)
  480. }
  481. }
  482. }
  483. fun isDownloading(): Boolean {
  484. return downloadResource.value?.status == Resource.Status.LOADING
  485. }
  486. fun isDownloadSuccess(): Boolean {
  487. return downloadResource.value?.status == Resource.Status.SUCCESS
  488. }
  489. fun getDownloadState(): LiveData<Resource<Int>> {
  490. return downloadResource
  491. }
  492. fun downloadRecipe() {
  493. if (mRecipeUrl.isNullOrEmpty()) {
  494. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  495. return
  496. }
  497. downloadResource.value = Resource(0, Resource.Status.LOADING)
  498. val downloadDir = globalApp().externalCacheDir.toString()
  499. val downloadName = System.nanoTime().toString()
  500. scopeNetLife {
  501. mRecipeUrl?.apply {
  502. val result = Get<File>(this) {
  503. setDownloadFileName(downloadName)
  504. setDownloadDir(downloadDir)
  505. addDownloadListener(object : ProgressListener() {
  506. override fun onProgress(p: Progress) {
  507. ThreadUtils.runOnMainThread {
  508. downloadResource.value =
  509. Resource(p.progress(), Resource.Status.LOADING)
  510. }
  511. }
  512. })
  513. }.await()
  514. if (!result.exists()) {
  515. ThreadUtils.runOnMainThread {
  516. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  517. }
  518. } else {
  519. prepareResource(result)
  520. }
  521. }
  522. }.catch {
  523. ThreadUtils.runOnMainThread {
  524. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  525. }
  526. }
  527. }
  528. private fun prepareResource(file: File) {
  529. try {
  530. val dst = ZipUtils.unzipFile(file, FoodDataProvider.getExtRecipeResourceDir())
  531. FileUtils.delete(file)
  532. if (dst.isNullOrEmpty()) {
  533. ThreadUtils.runOnMainThread {
  534. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  535. }
  536. return
  537. }
  538. val jsonFile = FoodDataProvider.getResourceConfigJsonPath(recipeNumber!!)
  539. if (!jsonFile.exists()) {
  540. ThreadUtils.runOnMainThread {
  541. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  542. }
  543. return
  544. }
  545. val jsonContent = FileKit.readFileToStringB(jsonFile)
  546. val contentData = GsonUtils.fromJson(jsonContent, RecipeDataConfig::class.java)
  547. // contentData.resetAllCodes()
  548. FoodDataProvider.getDatabase().runInTransaction {
  549. FoodDataProvider.getDatabase().recipeDao().apply {
  550. val categorys = queryAllCategory()
  551. val categoryMap = HashMap<String, DevRecipeCategory>()
  552. for (category in categorys) {
  553. categoryMap[category.number + ":" + category.lang] = category
  554. }
  555. for (devRecipeCategory in contentData.devRecipeCategorys) {
  556. if (categoryMap.containsKey(devRecipeCategory.number + ":" + devRecipeCategory.lang)) {
  557. devRecipeCategory.code =
  558. categoryMap[devRecipeCategory.number + ":" + devRecipeCategory.lang]?.code.toString()
  559. }
  560. }
  561. /**
  562. * 如果本地食谱存在的情况下
  563. * 下载在线食谱,需要删除本地食谱
  564. * **/
  565. contentData.devRecipes.forEach {
  566. var number = it.number ?: ""
  567. var lang = it.lang ?: "EN"
  568. deleteNumAndLangRecipe(number, lang)
  569. }
  570. //删除步骤 和其他一些
  571. recipeNumber?.let {
  572. deleteDevRecipeAccessorys(it)
  573. deleteDevRecipeCookingSteps(it)
  574. deleteDevRecipeFoods(it)
  575. deleteDevRecipeNutritions(it)
  576. deleteDevRecipeRelTags(it)
  577. deleteDevRecipePortionSizes(it)
  578. }
  579. // deleteRecipe(recipeNumber)
  580. insertDevAccessorys(contentData.devAccessorys)
  581. insertHotTags(contentData.devHotTags)
  582. insertDevPortraits(contentData.devPortraits)
  583. insertDevRecipeAccessorys(contentData.devRecipeAccessorys)
  584. insertDevRecipeCategorys(contentData.devRecipeCategorys)
  585. insertDevRecipeCookingSteps(contentData.devRecipeCookingSteps)
  586. insertDevRecipeFoods(contentData.devRecipeFoods)
  587. insertDevRecipeNutritions(contentData.devRecipeNutritions)
  588. insertDevRecipePortionSizes(contentData.devRecipePortionSizes)
  589. insertDevRecipeRelTags(contentData.devRecipeRelTags)
  590. insertDevRecipeTags(contentData.devRecipeTags)
  591. insertDevRecipes(contentData.devRecipes)
  592. }
  593. ThreadUtils.runOnMainThread {
  594. downloadResource.value = Resource(100, Resource.Status.SUCCESS)
  595. }
  596. }
  597. FoodDataProvider.getUserDatabase().runInTransaction {
  598. contentData.devRecipes.getOrNull(0)?.also {
  599. FoodDataProvider.getUserDatabase().userInfoDao().insertOnlineRecipe(
  600. UserOnLineRecipes(CURRENT_USER_ID, it.number ?: "")
  601. )
  602. }
  603. }
  604. } catch (e: Exception) {
  605. e.printStackTrace()
  606. ThreadUtils.runOnMainThread {
  607. downloadResource.value = Resource(0, Resource.Status.FAILURE)
  608. }
  609. }
  610. }
  611. companion object {
  612. const val ERR_NO_RECIPE_MATCH = -1
  613. }
  614. }