TopNavigationComponent.ets 10.1 KB
import { Action, CompDTO, Params, TopNavDTO } from 'wdBean';
import { LazyDataSource, Logger } from 'wdKit';
import { WDRouterRule } from 'wdRouter';
import { PageComponent } from './PageComponent';
import { ChannelSubscriptionLayout } from './ChannelSubscriptionLayout'

const TAG = 'TopNavigationComponent';

PersistentStorage.persistProp('channelIds', '');
PersistentStorage.persistProp('indexSettingChannelId', 0);

/**
 * 顶部页签导航栏/顶导
 */
@Component
export struct TopNavigationComponent {
  private tabsController: TabsController = new TabsController()
  @Prop _currentNavIndex: number;
  // 顶导当前选中/焦点下标
  @State currentTopNavSelectedIndex: number = 0;
  // 顶导数据
  @State @Watch('onTopNavigationDataUpdated') topNavList: TopNavDTO[] = []
  @State compList: LazyDataSource<CompDTO> = new LazyDataSource();
  @StorageProp('indexSettingChannelId') indexSettingChannelId: number = 0
  //我的频道id列表
  @State channelIds: number[] = []
  //本地缓存频道id列表
  @StorageProp('channelIds') storageChannelIds: string = ''
  @State homeChannelList: TopNavDTO[] = []
  // 我的频道列表
  @State myChannelList: TopNavDTO[] = []
  // 更多频道列表
  @State moreChannelList: TopNavDTO[] = []
  // 地方频道列表
  @State localChannelList: TopNavDTO[] = []
  readonly MAX_LINE: number = 1;

  //处理新闻tab顶导频道数据
  topNavListHandle() {
    let _channelIds: number [] = []
    let _myChannelList: TopNavDTO [] = []
    let _storageChannelIds: string [] = [] //list1
    let defaultMyChannelList: TopNavDTO[] = []
    let defaultList = [...this.topNavList]
    defaultList.sort((a, b) => {
      return a.num - b.num;
    });

    //defaultMyChannelList
    defaultList.forEach(item => {
      if (item.defaultPermitted === 1 || item.movePermitted === 0 || item.delPermitted === 0 || item.headlinesOn === 1) {
        defaultMyChannelList.push(item);
      }
      if (item.defaultPermitted === 1) {
        this.homeChannelList.push(item)
      }
    })

    //有缓存频道id
    if (this.storageChannelIds) {
      _storageChannelIds = this.storageChannelIds.split(',')
    }

    defaultMyChannelList.forEach(item => {
      item.myChannel = '1'
      if (item.defaultPermitted === 1) {
        item.homeChannel = '1'
      }
      let index = defaultList.findIndex(_item => _item.channelId === item.channelId)
      if (index !== -1) {
        defaultList.splice(index, 1)
      }
    })
    defaultList.unshift(...defaultMyChannelList)

    defaultList.forEach((item, index) => {
      if (this.storageChannelIds && _storageChannelIds.includes(String(item.channelId))) {
        item.myChannel = '1'
      }
      if (item.channelType === 2) {
        item.localChannel = '1'
      }
      if (index >= 11) {
        if (item.channelType === 1) {
          item.moreChannel = '1'
        }
      } else {
        if (item.channelType === 1 && item.myChannel !== '1') {
          item.moreChannel = '1'
        }
      }

      //频道分类
      if (item.myChannel === '1') {
        _myChannelList.push(item)
        _channelIds.push(item.channelId)
      } else if (item.moreChannel === '1') {
        this.moreChannelList.push(item)
      } else if (item.localChannel === '1') {
        this.localChannelList.push(item)
      }

    })

    this.channelIds = _channelIds
    this.myChannelList = _myChannelList

    //缓存首页频道
    if (!this.indexSettingChannelId) {
      AppStorage.set('indexSettingChannelId', this.homeChannelList[0].channelId)
    } else {
      let index = this.myChannelList.findIndex(_item => _item.channelId === this.indexSettingChannelId)
      this.currentTopNavSelectedIndex = index
    }
  }

  isBroadcast(item: TopNavDTO) {
    return item.name === '播报'
  }

  build() {
    Column() {
      // 顶部搜索、日报logo、早晚报
      RelativeContainer() {
        Stack({ alignContent: Alignment.Center }) {

          Image($r('app.media.background_search'))
            .width('100%')
            .height('100%')
            .objectFit(ImageFit.Contain)

          Row() {
            Image($r('app.media.icon_search'))
              .width(18)
              .height(18)

            Text('河南大雪')
              .fontColor($r('app.color.color_B0B0B0'))
              .fontSize($r('app.float.font_size_13'))
          }
          .alignItems(VerticalAlign.Center)
          .justifyContent(FlexAlign.Center)
        }
        .height(30)
        .width(123)
        .id('search')
        .alignRules({
          left: { anchor: "__container__", align: HorizontalAlign.Start },
          center: { anchor: "__container__", align: VerticalAlign.Center }
        })

        Image($r('app.media.icon_ren_min_ri_bao'))
          .width(72)
          .height(29)
          .onClick(() => {
            let taskAction: Action = {
              type: 'JUMP_INNER_NEW_PAGE',
              params: {
                pageID: 'E_NEWSPAPER'
              } as Params,
            };
            WDRouterRule.jumpWithAction(taskAction)
          })
          .id('ren_min')
          .alignRules({
            middle: { anchor: "__container__", align: HorizontalAlign.Center },
            center: { anchor: "__container__", align: VerticalAlign.Center }
          })

        Stack({ alignContent: Alignment.Center }) {
          Image($r('app.media.background_read_paper_home'))
            .width('100%')
            .height('100%')
            .objectFit(ImageFit.Contain)
          Row() {
            Image($r('app.media.icon_read_paper_home'))
              .width(18)
              .height(18)
            Text('早晚报')
              .fontColor($r('app.color.color_B0B0B0'))
              .fontSize($r('app.float.font_size_13'))
          }
          .alignItems(VerticalAlign.Center)
          .justifyContent(FlexAlign.Center)

        }
        .height(30)
        .width(124)
        .id('read')
        .alignRules({
          right: { anchor: "__container__", align: HorizontalAlign.End },
          center: { anchor: "__container__", align: VerticalAlign.Center }
        })
        .onClick(() => {

          let taskAction: Action = {
            type: 'JUMP_INNER_NEW_PAGE',
            params: {
              pageID: 'MorningEveningPaper'
            } as Params,
          };
          WDRouterRule.jumpWithAction(taskAction)
        })
      }
      .width('100%')
      .height(40)
      .visibility(this._currentNavIndex == 0 ? Visibility.Visible : Visibility.None)

      // 频道分类list
      Stack({ alignContent: Alignment.TopEnd }) {
        Tabs({ index: this.currentTopNavSelectedIndex, controller: this.tabsController }) {
          ForEach(this._currentNavIndex === 0 ? this.myChannelList : this.topNavList, (navItem: TopNavDTO, index: number) => {
            TabContent() {
              if (!this.isBroadcast(navItem)) {
                PageComponent({
                  currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
                  navIndex: index,
                  pageId: navItem.pageId + '',
                  channelId: navItem.channelId + ''
                })
              }
            }
            .tabBar(this.tabBarBuilder(navItem, index))
          }, (navItem: TopNavDTO) => JSON.stringify(navItem));
        }
        .barHeight($r('app.float.top_tab_bar_height'))
        .barMode(BarMode.Scrollable)
        .vertical(false)
        .onChange((index: number) => {
          Logger.info(TAG, `onChange index : ${index}`);
          if (!this.isBroadcast(this.myChannelList[index])) {
            this.currentTopNavSelectedIndex = index;
          } else {
            // 跳转到播报页面
            let taskAction: Action = {
              type: 'JUMP_INNER_NEW_PAGE',
              params: {
                pageID: 'BroadcastPage',
                id: this.myChannelList[index].pageId
              } as Params,
            };
            WDRouterRule.jumpWithAction(taskAction)
            this.tabsController.changeIndex(this.currentTopNavSelectedIndex)
          }
        })

        // 分类列表最右侧频道设置
        if (this._currentNavIndex === 0) {
          ChannelSubscriptionLayout({
            currentTopNavSelectedIndex: $currentTopNavSelectedIndex,
            indexSettingChannelId: this.indexSettingChannelId,
            homeChannelList: this.homeChannelList,
            myChannelList: $myChannelList,
            moreChannelList: $moreChannelList,
            localChannelList: $localChannelList,
            channelIds: $channelIds,
            changeTab: (index) => {
              this.tabsController.changeIndex(index)
            }
          })
        }
      }

    }
  }

  @Builder
  tabBarBuilder(item: TopNavDTO, index: number) {
    Column() {
      Text(item.name)
        .fontSize(this.currentTopNavSelectedIndex === index ? $r('app.float.selected_text_size') : $r('app.float.normal_text_size'))
        .fontWeight(this.currentTopNavSelectedIndex === index ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(Color.Black)
        .padding({ top: $r('app.float.top_tab_item_padding_top') })
        .maxLines(this.MAX_LINE)
      Divider()
        .width(16)
        .strokeWidth(2)// 分割线粗细度。
        .padding({ top: 2 })
        .color(Color.Red)
        .opacity(this.currentTopNavSelectedIndex === index ? 1 : 0)
    }
    .hoverEffect(HoverEffect.Highlight)
    .constraintSize({
      minWidth: $r('app.float.top_tab_item_min_width'),
      maxWidth: $r('app.float.top_tab_item_max_width')
    })
    // .margin({ right: 36 })
    // .backgroundColor(Color.Black)
    .padding({
      left: $r('app.float.top_tab_item_padding_horizontal'),
      right: $r('app.float.top_tab_item_padding_horizontal'),
      bottom: $r('app.float.top_tab_item_padding_bottom')
    })
    .id(`col_tabBar${index}`)
    .margin({ right: this.myChannelList.length === index + 1 ? 36 : 0 })
  }

  aboutToAppear() {
    //处理新闻tab顶导频道数据
    if (this._currentNavIndex === 0) {
      this.topNavListHandle()
    }
  }

  aboutToDisappear() {
    AppStorage.set('channelIds', this.channelIds.join(','))
  }

  onTopNavigationDataUpdated() {
    Logger.info(TAG, `onTopNavigationDataUpdated currentTopNavIndex: ${this.currentTopNavSelectedIndex},topNavList.length:${this.topNavList.length}`);
  }
}