DiaryView.ets 7.9 KB

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