index.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import PageContainerBehavior from "../../../../core/behavior/page-container.behavior";
  2. // module/chats/pages/index/index.ts
  3. interface ScrollIntoViewEvent {
  4. detail: string;
  5. }
  6. interface HandleEvent {
  7. detail: { component: 'guide' | 'questionnaire', scroll?: boolean }
  8. }
  9. interface Message extends Omit<HandleEvent['detail'], 'scroll'> {
  10. id: string;
  11. }
  12. function getScrollcontext(this: any) {
  13. return this as {
  14. scroll: WechatMiniprogram.ScrollViewContext,
  15. timer: number;
  16. }
  17. }
  18. Component({
  19. behaviors: [PageContainerBehavior],
  20. lifetimes: {
  21. attached() {
  22. const component = this.data.component as 'guide' | 'questionnaire'
  23. this.handle({ detail: { component, scroll: true } });
  24. },
  25. ready() {
  26. wx.createSelectorQuery().select('#scrollview').node().exec((res) => {
  27. getScrollcontext.call(this).scroll = res[0].node;
  28. })
  29. }
  30. },
  31. properties: {
  32. component: { type: String, value: 'guide' }
  33. },
  34. data: {
  35. messages: {} as Record<number, Message>,
  36. lastId: '',
  37. },
  38. observers: {
  39. 'messages.**'(messages) {
  40. const message = Object.values(messages).pop() as Message;
  41. this.setData({ lastId: message?.id });
  42. }
  43. },
  44. methods: {
  45. handle(event: HandleEvent) {
  46. const index = Object.keys(this.data.messages).length;
  47. this.setData({
  48. [`messages.${index}`]: <Message>{
  49. id: `${this.is.replace(/\//g, '_')}-${index}`,
  50. component: event.detail?.component,
  51. }
  52. });
  53. if (event.detail?.scroll) this.scrollIntoView()
  54. },
  55. scrollIntoView(event?: ScrollIntoViewEvent) {
  56. clearTimeout(getScrollcontext.call(this).timer);
  57. const id = event?.detail ?? this.data.lastId;
  58. getScrollcontext.call(this).timer = setTimeout(() => {
  59. getScrollcontext.call(this).scroll?.scrollIntoView(`#${id}`, { alignment: 'end' });
  60. }, 300)
  61. },
  62. }
  63. })