DiaryView.ets 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. import { IBestToast, userInfo, UserInfo, YTAvoid, yTRouter, yTToast } from "basic"
  2. import { DiaryCalendarPicker } from "../components/DiaryCalendarPicker"
  3. import { DiaryTitleItem } from "../components/DiaryTitleItem"
  4. import { DoubleConfirm } from "../components/DoubleConfirm"
  5. import { LoginComponent } from "../components/LoginComponent"
  6. import { DiaryData, PageStatus } from "../models"
  7. import { DateUtils } from "../utils/DateUtils"
  8. import { DiaryViewModel } from "../viewModels/DiaryViewModel"
  9. /**
  10. * 日记页面
  11. */
  12. @Component
  13. export struct DiaryView {
  14. @StorageProp(YTAvoid.SAFE_TOP_KEY) safeTop: number = 0
  15. @State Vm: DiaryViewModel = new DiaryViewModel()
  16. @State ShowLoginDialog: boolean = false
  17. @StorageProp(UserInfo.KEY) @Watch('loginStateChanged') userInfo: UserInfo = userInfo
  18. private linearInfo: LinearGradientOptions = {
  19. colors: [ ['#B9FD2A', 0.01], ['#F5FD6D', 1] ],
  20. angle: 110
  21. }
  22. /**
  23. * 登录状态发生变化
  24. */
  25. loginStateChanged(){
  26. console.log('登录状态发生变化 登录状态为 ' + this.userInfo.checkLogin())
  27. const loginState = this.userInfo.checkLogin()
  28. if(loginState){
  29. this.ShowLoginDialog = false
  30. this.reloadDiaryData()
  31. } else {
  32. this.Vm.diaryDataList = []
  33. this.Vm.dateList = []
  34. }
  35. }
  36. /**
  37. * 跳转日记详情
  38. * @param id 日记 id (可选),没有 id 表示新增日记
  39. */
  40. routerDiaryPage(id?: number) {
  41. yTRouter.pushPathByName("IncreaseDiaryPage", {
  42. 'id': id,
  43. 'PageStatus': PageStatus.DIARY
  44. } as Record<string, string | number>);
  45. }
  46. /**
  47. * 删除日记
  48. * @param index
  49. */
  50. decreaseDiary(index: number){
  51. yTToast.openToast(wrapBuilder(DoubleConfirm), {
  52. text: "确定删除该篇日记吗?",
  53. click: async () => {
  54. yTToast.hide()
  55. let ans = await this.Vm.deleteDiaryLog(index)
  56. if(ans){
  57. IBestToast.show({ message: '删除了日记' })
  58. this.reloadDiaryData()
  59. }
  60. }
  61. })
  62. }
  63. /**
  64. * 搜索日记
  65. */
  66. routerSearchPage(){
  67. yTRouter.pushPathByName("DiarySearchPage", null)
  68. }
  69. /**
  70. * 打开日期选择器
  71. */
  72. openDatePicker(){
  73. let controll: CustomDialogController = new CustomDialogController({
  74. builder: DiaryCalendarPicker({
  75. dateList: this.Vm.dateList,
  76. onConfirm: (value) => {
  77. this.toDiaryHead(value)
  78. controll.close()
  79. },
  80. onCancel: () => {
  81. controll.close()
  82. }
  83. }),
  84. alignment: DialogAlignment.Center,
  85. })
  86. controll.open()
  87. }
  88. /**
  89. * 跳转到指定的日期的日记索引 ( 如果找不到指定的日期, 跳转到最近的比目标值大的索引 )
  90. * @param date 选择的 日期
  91. */
  92. toDiaryHead(date: Date) {
  93. console.info("calendar onAccept:" + JSON.stringify(date));
  94. let ans = DateUtils.formatDateToCustomString(date, false);
  95. let target = 0;
  96. for (let i = 0; i < this.Vm.dateList.length; i++) {
  97. let current = this.Vm.dateList[i]
  98. if(current >= ans) {
  99. target = i;
  100. }
  101. }
  102. console.log("target " + target)
  103. this.Vm.scroller.scrollToIndex(target, true, ScrollAlign.START)
  104. }
  105. /**
  106. * 重新加载日记数据
  107. */
  108. reloadDiaryData() {
  109. if(this.userInfo.checkLogin()){
  110. this.Vm.queryDiaryLogList(DateUtils.formatDateToCustomString(new Date(), false))
  111. } else {
  112. this.ShowLoginDialog = true
  113. }
  114. }
  115. aboutToAppear(): void {
  116. this.reloadDiaryData()
  117. }
  118. build() {
  119. Stack(){
  120. Column() {
  121. // title
  122. Row() {
  123. Image($r("app.media.calendar"))
  124. .width(30)
  125. .aspectRatio(1)
  126. .onClick(() => {
  127. this.openDatePicker()
  128. })
  129. Text("日记本")
  130. .fontSize(20)
  131. Image($r("app.media.Search"))
  132. .width(30)
  133. .aspectRatio(1)
  134. .onClick(this.routerSearchPage)
  135. }
  136. .width("100%")
  137. .justifyContent(FlexAlign.SpaceBetween)
  138. .padding({ top: this.safeTop + 22, left: 16, right: 16, bottom: 33 })
  139. // swiper
  140. Stack({ alignContent: Alignment.BottomEnd }) {
  141. // 日记列表
  142. List({ space: 16, scroller: this.Vm.scroller }) {
  143. // 空数据页面
  144. if(this.Vm.diaryDataList.length === 0) {
  145. ListItem(){
  146. Column({space: 12}){
  147. Row({space: 8}){
  148. Text("+")
  149. Text("去添加")
  150. }
  151. .borderRadius(8)
  152. .linearGradient(this.linearInfo)
  153. .alignItems(VerticalAlign.Center)
  154. .justifyContent(FlexAlign.Center)
  155. .border({width: 1, color: Color.Black})
  156. .padding({ left: 16, top: 12, right: 16, bottom: 12})
  157. .onClick(() => {
  158. this.routerDiaryPage()
  159. })
  160. Text("暂无记录~")
  161. .fontSize(14)
  162. .fontWeight(400)
  163. }
  164. .width("100%")
  165. .height("100%")
  166. .alignItems(HorizontalAlign.Center)
  167. .padding({ top: '40%'})
  168. // .justifyContent(FlexAlign.Center)
  169. }
  170. .layoutWeight(1)
  171. .width("100%")
  172. }
  173. ForEach(this.Vm.dateList, (groupTitle: string, index: number) => {
  174. ListItemGroup({
  175. header: this.DiaryHead(groupTitle),
  176. }) {
  177. ForEach(this.Vm.diaryDataList.filter((item) => item.diaryDate == groupTitle), (item: DiaryData, i: number) => {
  178. ListItem() {
  179. DiaryTitleItem({
  180. title: item.title,
  181. onClickBack: () => {
  182. this.routerDiaryPage(item.id)
  183. },
  184. onActionBack: (event: GestureEvent) => {
  185. console.log("触发删除")
  186. this.decreaseDiary(item.id ?? -1)
  187. }
  188. })
  189. }
  190. .swipeAction({
  191. end: this.DiaryDel(item.id),
  192. edgeEffect: SwipeEdgeEffect.None
  193. })
  194. }, (item: DiaryData) => item.id?.toString() + item.title!)
  195. }
  196. }, (groupTitle: string, index: number) => groupTitle)
  197. }
  198. .width("100%")
  199. .height("100%")
  200. .scrollBar(BarState.Off)
  201. .sticky(StickyStyle.Header)
  202. // 增加日记按钮
  203. Row() {
  204. Image($r("app.media.add_Img"))
  205. .width(50)
  206. .aspectRatio(1)
  207. }
  208. .onClick(() => {
  209. this.routerDiaryPage()
  210. })
  211. .width(50)
  212. .aspectRatio(1)
  213. .borderRadius(30)
  214. .margin({ bottom: 16 })
  215. .alignItems(VerticalAlign.Center)
  216. .justifyContent(FlexAlign.Center)
  217. .linearGradient(this.linearInfo)
  218. }
  219. .width("100%")
  220. .layoutWeight(1)
  221. .backgroundColor(Color.White)
  222. .padding({ left: 16, right: 16, top: 13 })
  223. .borderRadius({
  224. topLeft: 28, topRight: 28
  225. })
  226. }
  227. .width("100%")
  228. .height("100%")
  229. .linearGradient(this.linearInfo)
  230. .onVisibleAreaChange([0, 1], (isExpanding: boolean, currentRatio: number) => {
  231. if(isExpanding) {
  232. console.log("组件出来了")
  233. this.reloadDiaryData()
  234. } else {
  235. console.log("组件退了")
  236. }
  237. })
  238. if(this.ShowLoginDialog){
  239. LoginComponent()
  240. }
  241. }
  242. .width("100%")
  243. .height("100%")
  244. }
  245. // 日记时间组 - 头部组件
  246. @Builder
  247. DiaryHead(time: string) {
  248. Row(){
  249. Text(time)
  250. }
  251. .width("100%")
  252. .backgroundColor(Color.White)
  253. }
  254. // 日记条目删除组件
  255. @Builder
  256. DiaryDel(index: number) {
  257. Row() {
  258. Row(){
  259. Text("删除")
  260. .fontSize(16)
  261. .fontColor(Color.White)
  262. }
  263. .width(60)
  264. .height("100%")
  265. .backgroundColor(Color.Red)
  266. .alignItems(VerticalAlign.Center)
  267. .justifyContent(FlexAlign.Center)
  268. .borderRadius({
  269. topLeft: 20, bottomLeft: 20
  270. })
  271. .onClick(() => {
  272. this.decreaseDiary(index)
  273. })
  274. }
  275. .padding({left: 10})
  276. }
  277. }