【公众号搬运】React-Native开发鸿蒙NEXT(8)

208 阅读6分钟

React-Native开发鸿蒙NEXT(8)

原创 悬空八只脚 悬空八只脚 2024年09月30日 21:37 江苏

  主体开发完了也上架了,现在就剩下社区RN了。多个RN的切换加载需要额外处理。单个RN是用RNApp来加载的,多个的话得改成RNSurface来加载。demo里是有多bundle的加载实现的,后面再研究。

  先把APP首页的社区列表做出来。当初开发的时候列表是单独做的,没有用社区RN的组件。也是为了加快开发进度,复制过去改改路径就完事了。往往屎山就是这么造出来的。这次还是保留原样,后面的RN社区部分工作量感觉不小,就不再这上面花功夫了。还有个原因就是这经费问题迟迟不到位,用爱发电难免影响点积极性。虽说是列表,其实也把一整套处理富文本的逻辑都搬过去了,只是没用上多少,因为列表只是展示个文章的标题和缩略图,正文是不展示的。倒也不是白下力气,这部分后面去处理社区RN的改造是可以复用的。社区RN当年做的时候就是照着头条抄的,复杂点的地方在于富文本的排版处理。发帖有@人和#话题两个基本功能,需要针对@与#标签来识别。现在回过头来看当年写的处理逻辑真是头皮发麻。这要是不是屎山那就天下无屎了。

const renderRowText = (rowItem, index) => {
  // console.log('rowItem = '+ rowItem);
  /* 以10个字符作为最大长度的限制(测试),如果超过了10个字符,显示"...全文",裁剪是先取加下一个内容的长度再判断的,可能会比手动计算
     的短一点,可以判断下一个内容是不是纯文本,如果是纯文本还是可以截字的,但@#【图片】是不能截取的必须全部显示
   */
  // 内容计算
  let _kMaxLength = kMaxLength;
  // 是否需要行数控制 true 清除行数控制 ,false :不清除行数控制
  let _kClearNumberOfLine = props.clearNumberOfLine;
  let content = currentLength;
  // 输出的控件数组
  let textArr = [];
  if (rowItem.length == 0) {
    textArr.push(<Text></Text>);
    return textArr;
  }
  // 字号
  let _kFontSize = kFontSize;
  // 已读颜色
  let kReadColor = '#999';
  // 未读颜色
  //let kUnReadColor = "rgba(0,0,0,0.85)";
  let kUnReadColor = textColor;
  // "查看原图"颜色
  let kImgColor = '#406599';
  // @和#颜色
  let kAtAndTopicColor = '#406599';
  // 行高
  let kLineHeight = scaleHeight(24);
  // 是否已读
  let kHasBeenRead = !!!props.hasBeenRead ? false : props.hasBeenRead;
  //data = "↵funew↵&lt;a class=&quot;#&quot; href= &quot;id = 1066929428594036736&quot; title = &quot;#今天吃什么#&quot;/&gt;↵funew↵泉屋↵funew↵&lt;a class=&quot;#&quot; href= &quot;id = 1066929428594036736&quot; title = &quot;#今天吃什么#&quot;/&gt;↵funew↵"
  // let isOver = false;
  // 富文本区切数组
  let spliteArr = [];
  // 分割字符串
  spliteArr = Array.from(rowItem);
  // 当存在回车换行的时候,如果一行计算的字数< 最大字数/最多行数,将统计数字撑满
  if (linesArr.length > 0 && index > 0) {
    if (
      currentLength < kMaxLineLength * index &&
      currentLength < kMaxLength
    ) {
      currentLength = kMaxLineLength * index;
      console.log('有回车,撑满一行:' + currentLength);
    }
  }
  // 数组处理
  spliteArr.map((item, index1) => {
    //content += item;
    // 如果想要替换所有指定的字符串,可以用while循环
    while (item.indexOf('&nbsp;') >= 0) {
      item = item.replace('&nbsp;', ' ');
    }
    if (
      content >= kMaxLength &&
      (!!!_kClearNumberOfLine || !_kClearNumberOfLine)
    ) {
      console.log('达到最大长度,不再处理22222');
      isOver = true;
      // 发送超长通知给调用页面以便做UI处理
      DeviceEventEmitter.emit('RichTextContentIsOver');
      if (!isOver1 && !hideShowAllText) {
        setIsOver1(true);
      }
      return;
    } else {
      // 过滤掉空值<统一不过滤,换行后的空行需要显示>
      // if(item.trim().length != 0){
      if (1 == 1) {
        // 判定是不是标签
        if (item.indexOf('<') != -1) {
          // 标签
          // 套入<div>中
          if (item.indexOf('<div') != 0) {
            item = '<div>' + item;
            item = item + '</div>';
          }
          // item = "<div>" + item;
          // item = item + "</div>";
          // 解析
          let $ = Cheerio.load(item);
          // 获得富文本中设定的字号
          let style = $('span').attr('style');
          if (!!style) {
            let arr = style.split(';');
            for (let attr of arr) {
              if (attr.indexOf('font-size') != -1) {
                let size = attr
                  .replace('font-size:', '')
                  .replace('px', '')
                  .trim();
                let int_size = parseInt(size);
                if (!!int_size) {
                  kFontSize = int_size;
                  _kFontSize = int_size;
                }
              }
            }
          }
          if (!enabledHideImg) {
            let markArr = $('div').find('a');
            renderHerfImage(
              markArr,
              textArr,
              content,
              kMaxLength,
              kClearNumberOfLine,
              kImgColor,
              kFontSize,
              kAtAndTopicColor,
              index1,
              $,
            );
            let imageArr = $('div').find('img');
            renderHerfImage(
              imageArr,
              textArr,
              content,
              kMaxLength,
              kClearNumberOfLine,
              kImgColor,
              kFontSize,
              kAtAndTopicColor,
              index1,
              $,
            );
          }
          /* 这段逻辑是为了处理之前因为标签的结尾">"后面没有跟上区切字符,导致的可能出现">"还有纯文本的情况,现在已经添
             加了结束标签的区切字符,这里保留以兼容以前的老数据
          */
          // 过滤掉a标签与标签之间的内容,Cheerio的text方法会包含child元素的text一起输出
          let removedAItem = item.replace(/<a.*?>(.*?)</a>/g, '');
          // 删除多余不必要的div嵌套,Cheerio的text方法会包含child元素的text一起输出,存在多个div会重复输出,如<div><div><div>23423423424</div></div></div>,数字会输出两遍
          // removedAItem = removedAItem.replace(/<div.*?>(.*?)</div>/g,"");
          // let $1 = Cheerio.load(removedAItem);
          // let markAText = $1("div").text();
          removedAItem = item.replace(/<[^>]+>/g, '');
          let markAText = removedAItem;
          // let markAText = removedAItem;
          if (!_.isEmpty(markAText)) {
            // 文本
            var tempContent = content;
            content += markAText.length;
            // 超长判断
            if (
              content > kMaxLength &&
              (!!!_kClearNumberOfLine || !_kClearNumberOfLine)
            ) {
              // 超长
              if (!isOver) {
                // 文本可以尝试截位
                if (tempContent < kMaxLength) {
                  markAText = markAText
                    .toString()
                    .substring(0, kMaxLength - tempContent);
                  textArr.push(
                    <Text
                      key={index1 + '-index1-'}
                      style={
                        /*kHasBeenRead
                                              ? {
                                                  color: kReadColor,
                                                  fontSize: kFontSize,
                                                  lineHeight: lineHeight,
                                                  //height: kLineHeight
                                                  //backgroundColor: 'green',
                                              }
                                              : {
                                                  color: kUnReadColor,
                                                  fontSize: kFontSize,
                                                  lineHeight: lineHeight,
                                                  //height: kLineHeight
                                                  //backgroundColor: 'green',
                                              }*/
                        getReadTextStyle(
                          lineHeight,
                          kReadColor,
                          kUnReadColor,
                          kFontSize,
                          kHasBeenRead,
                        )
                      }>
                      {markAText}
                    </Text>,
                  );
                }
              }
              isOver = true;
              // 发送超长通知给调用页面以便做UI处理
              DeviceEventEmitter.emit('RichTextContentIsOver');
              // FIXME:这里不需要???
              if (!isOver1 && !hideShowAllText) {
                setIsOver1(true);
              }
              return;
            } else {
              // 正常显示
              textArr.push(
                <Text
                  key={index1 + '-index1-'}
                  style={getReadTextStyle(
                    lineHeight,
                    kReadColor,
                    kUnReadColor,
                    kFontSize,
                    kHasBeenRead,
                  )}
                  onLongPress={() => {
                    copy();
                  }}
                  suppressHighlighting={true}>
                  {markAText}
                </Text>,
              );
              // 拼接到文本字符串中
              textString = textString + markAText;
            }
          }
          // }
        } else {
          // 纯文本
          var tempContent = content;
          content += item.length;
          // 超长判断
          if (
            content > kMaxLength &&
            (!!!_kClearNumberOfLine || !_kClearNumberOfLine)
          ) {
            // 超长
            //if(!isOver){
            if (1 == 1) {
              // 文本可以尝试截位
              if (tempContent < kMaxLength) {
                item = item.toString().substring(0, kMaxLength - tempContent);
                textArr.push(
                  <Text
                    key={index1 + '-index1-'}
                    style={getReadTextStyle(
                      lineHeight,
                      kReadColor,
                      kUnReadColor,
                      kFontSize,
                      kHasBeenRead,
                    )}>
                    {item}
                  </Text>,
                );
              }
              // textArr.push(<Text>
              //     <Text style={{
              //         color: kDotColor,
              //         fontSize: kFontSize,
              //         //height: kLineHeight
              //     }}>...</Text>
              //     <Text style={{
              //         color: kZenbuColor,
              //         fontSize: kFontSize,
              //         //height: kLineHeight
              //     }}>全文</Text>
              // </Text>);
            }
            isOver = true;
            // 发送超长通知给调用页面以便做UI处理
            DeviceEventEmitter.emit('RichTextContentIsOver');
            if (!isOver1 && !hideShowAllText) {
              setIsOver1(true);
            }
            return;
          } else {
            // 正常显示
            textArr.push(
              <Text
                key={index1 + '-index1-'}
                style={getReadTextStyle(
                  lineHeight,
                  kReadColor,
                  kUnReadColor,
                  kFontSize,
                  kHasBeenRead,
                )}
                onLongPress={() => {
                  copy();
                }}
                suppressHighlighting={true}>
                {item}
              </Text>,
            );
            // 拼接到文本字符串中
            textString = textString + item;
          }
        }
      }
    }
  });
  // console.log(textArr);
  currentLength += content;
  return textArr;
};

  话说回来:当年也是想做个好人的。时间紧任务重,屎山的出现自有它的无奈。

// 处理文本
const _dealWithText = (item, currentLength) => {};
// 处理<a>标签
const _dealWithATag = item => {};
// 创建一个用于显示纯文本的Text组件
const _createTextObjectForString = item => {};
// 创建一个用于显示<a>标签内容(@,#,[图片])的Text组件
const _createTextObjectForTag = item => {};

// 创建一个用于显示"...全文"的Text组件
const _createTextObjectForZenbu = item => {};

  也许,把社区RN开发完,若还是这样吊儿郎当闲着就回过头来把这个富文本的组件好好改改,就当重新学习了。

  十一长假也没什么计划,感觉就这样吧。这几天啥疯掉的股市和自己也没什么关系,整个一无欲无求?继续开发下去吧,总得通过项目来保持下学习的状态。虽然目前看学习并不能带来什么短期收益和机会。但目标总是要有的,哪怕仅仅是为了一杯冰美式:)


关注该公众号【悬空八只脚