抱歉,您没有提供第五篇的具体内容,请提供相关文本,以便我为您改写为一个新的长尾词。

2026-05-27 18:481阅读0评论SEO问题
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1503个文字,预计阅读时间需要7分钟。

抱歉,您没有提供第五篇的具体内容,请提供相关文本,以便我为您改写为一个新的长尾词。

前言:由于中间几个月项目加班,导致没有时间更新,最近一段时期对前端进行了重构,增加了许多页面,如登录、注册、关注、个人中心等,目前写这个纯属于个人爱好,所以会间断。

前言

由于中间几个月项目天天加班,导致没没时间更新,最近一段时间对前端进行了重构,加了很多页面,如登录、注册、关注、个人中心等,目前写这个纯属业余个人爱好,所以断断续续的继续在做......

前端地址:www.pgyer.com/dtok
后端服务器地址:47.95.209.198:8181/

注释:由于本人的apple id无法打包ios、所以暂时只打包的android版本,ios版本正在解决账号问题

效果如下:

架构更新

之前技术采用flutter做的前端,后端api则对接的是抖音官方api,由于抖音的官方api更新频繁,导致经常播放不了,所以索性自己来写服务器后端api,那么后端api采用了那些技术咧

  • springcloud 主要是后台控制面板 演示地址:47.95.209.198:8181/login
  • elasticsearch 主要对视频数据离线查询
  • ipfs 用于分布式节点存储短视频
  • ethereum 用户激励用户存储短视频、毕竟买服务器存花费够大的
界面更新
  • 支持国家化,多语言切换
  • ipfs上传、下载文件
  • 登录页面
  • 注册页面
  • 上下轮播时优化播放效果
  • 点赞功能

其他功能还在继续完善,各位喜欢的话欢迎点个star 前端项目地址:github.com/telsacoin/telsavideo
后端需要的话请留下邮箱

抱歉,您没有提供第五篇的具体内容,请提供相关文本,以便我为您改写为一个新的长尾词。

本期最大的优化就是国际化,flutter国家化按以下步骤

在pubspec.yaml文件加上

flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.17.0 # Add this line ffi: ^1.1.2

在底部的flutter设置里添加

# The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true generate: true # Add this line 新建多语言包

在lib目录新建子目录l10n
里面添加app_zh.arb文件
内容如下:

{ "home_top_foryou":"推荐", "home_top_following":"关注", "home_share":"分享", "home_buttom_title":"首页", "home_buttom_discover":"发现", "home_buttom_notification":"通知", "home_buttom_persion":"我" }

在main文件引用

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

在build里加入多语言检测及支持的代码

return MaterialApp( debugShowCheckedModeBanner: false, onGenerateTitle: (context) => AppLocalizations.of(context)!.home_buttom_title, home: SplashScreen(), localeResolutionCallback: ( Locale? locale, Iterable<Locale> supportedLocales, ) { return locale; }, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, theme: ThemeData( textSelectionTheme: TextSelectionThemeData( cursorColor: Colors.white, ), splashColor: Colors.transparent, highlightColor: Colors.transparent, primarySwatch: Colors.red, primaryColor: Colors.black, indicatorColor: Colors.white, tabBarTheme: TabBarTheme(), ), /* initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, */ builder: (context, child) { return ScrollConfiguration( behavior: MyBehavior(), child: child!, ); }, );

然后在需要引用的位置加入

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

调用的位置

AppLocalizations.of(context)!.home_top_foryou 至此,国际化就完成了

另外本地针对播放模块进行了优化,将代码拆分到videoplayer.dart文件.一来是方便代码阅读,而来可以作为子组件使用,其他的代码写得太冗余也在继续拆开,独立出来,各位感兴趣的可以关注项目的进展。

采用FutureBuilder对界面请求数据异步处理,当加载完成后才播放,效果更佳

代码如下:

return FutureBuilder<DTok>( future: videos, builder: (context, snapshot) { print(snapshot.connectionState); if (snapshot.connectionState == ConnectionState.waiting) { return loading; // return Column( // crossAxisAlignment: CrossAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center, // children: [ // loading, // Visibility( // visible: snapshot.hasData, // child: PageView.builder( // controller: foryouController, // onPageChanged: (index) { // //when the video is changing, release the previous video instance. // //disposeVideo(); // setState(() {}); // }, // scrollDirection: Axis.vertical, // itemCount: snapshot.data!.itemList!.length, // itemBuilder: (context, index) { // var item = snapshot.data!.itemList![index]; // return Videoplayer( // item: item, // width: MediaQuery.of(context).size.width, // heigth: MediaQuery.of(context).size.height, // ); // }), // ) // ], // ); } else if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Error, Please restart your app agagin') ], ); } else if (snapshot.hasData) { try { return PageView.builder( controller: foryouController, onPageChanged: (index) { //when the video is changing, release the previous video instance. //disposeVideo(); //setState(() {}); }, scrollDirection: Axis.vertical, itemCount: snapshot.data!.itemList!.length, itemBuilder: (context, index) { var item = snapshot.data!.itemList![index]; return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); }); } catch (e) { return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, color: Colors.black, child: Center( child: Text( 'Error, Please restart your app again.', style: TextStyle(color: Colors.white), )), ); } } else { // empty data return loading; } } else { return Text('State: ${snapshot.connectionState}'); } });

这里可以看到当snapshot.connectionState == ConnectionState.waiting的时候请求的数据正在加载中,则显示加载的图标loading

当snapshot.connectionState == ConnectionState.done 时,此时数据已经加载完毕,但是加载完毕有可能也没有数据,所以需要判断不同的情况

当加载出现异常情况则显示异常的widget

if (snapshot.hasError) { return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Error, Please restart your app agagin') ], ); }

当if (snapshot.hasData)则说明有返回值,但是这个返回值不一定就是我们需要的数据,所以还需要try catch一下,保证呈现给用户的界面是正常的

try { return PageView.builder( controller: foryouController, onPageChanged: (index) { //when the video is changing, release the previous video instance. //disposeVideo(); //setState(() {}); }, scrollDirection: Axis.vertical, itemCount: snapshot.data!.itemList!.length, itemBuilder: (context, index) { var item = snapshot.data!.itemList![index]; return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); }); } catch (e) { return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, color: Colors.black, child: Center( child: Text( 'Error, Please restart your app again.', style: TextStyle(color: Colors.white), )), ); } }

其他情况则返回加载状态,因为没有数据返回

另外加载videoplay的时候把width、heigth传入到下一个控件,这样好计算界面呈现的宽度与高度

return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); 结语

请继续关注本博客,其他页面持续更新完成,源码地址:telsavideo, 欢迎fork和star,谢谢!!!

再次奉上演示地址:
前端地址:www.pgyer.com/dtok
后端服务器地址:47.95.209.198:8181/

本文共计1503个文字,预计阅读时间需要7分钟。

抱歉,您没有提供第五篇的具体内容,请提供相关文本,以便我为您改写为一个新的长尾词。

前言:由于中间几个月项目加班,导致没有时间更新,最近一段时期对前端进行了重构,增加了许多页面,如登录、注册、关注、个人中心等,目前写这个纯属于个人爱好,所以会间断。

前言

由于中间几个月项目天天加班,导致没没时间更新,最近一段时间对前端进行了重构,加了很多页面,如登录、注册、关注、个人中心等,目前写这个纯属业余个人爱好,所以断断续续的继续在做......

前端地址:www.pgyer.com/dtok
后端服务器地址:47.95.209.198:8181/

注释:由于本人的apple id无法打包ios、所以暂时只打包的android版本,ios版本正在解决账号问题

效果如下:

架构更新

之前技术采用flutter做的前端,后端api则对接的是抖音官方api,由于抖音的官方api更新频繁,导致经常播放不了,所以索性自己来写服务器后端api,那么后端api采用了那些技术咧

  • springcloud 主要是后台控制面板 演示地址:47.95.209.198:8181/login
  • elasticsearch 主要对视频数据离线查询
  • ipfs 用于分布式节点存储短视频
  • ethereum 用户激励用户存储短视频、毕竟买服务器存花费够大的
界面更新
  • 支持国家化,多语言切换
  • ipfs上传、下载文件
  • 登录页面
  • 注册页面
  • 上下轮播时优化播放效果
  • 点赞功能

其他功能还在继续完善,各位喜欢的话欢迎点个star 前端项目地址:github.com/telsacoin/telsavideo
后端需要的话请留下邮箱

抱歉,您没有提供第五篇的具体内容,请提供相关文本,以便我为您改写为一个新的长尾词。

本期最大的优化就是国际化,flutter国家化按以下步骤

在pubspec.yaml文件加上

flutter: sdk: flutter flutter_localizations: sdk: flutter intl: ^0.17.0 # Add this line ffi: ^1.1.2

在底部的flutter设置里添加

# The following section is specific to Flutter. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true generate: true # Add this line 新建多语言包

在lib目录新建子目录l10n
里面添加app_zh.arb文件
内容如下:

{ "home_top_foryou":"推荐", "home_top_following":"关注", "home_share":"分享", "home_buttom_title":"首页", "home_buttom_discover":"发现", "home_buttom_notification":"通知", "home_buttom_persion":"我" }

在main文件引用

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

在build里加入多语言检测及支持的代码

return MaterialApp( debugShowCheckedModeBanner: false, onGenerateTitle: (context) => AppLocalizations.of(context)!.home_buttom_title, home: SplashScreen(), localeResolutionCallback: ( Locale? locale, Iterable<Locale> supportedLocales, ) { return locale; }, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, theme: ThemeData( textSelectionTheme: TextSelectionThemeData( cursorColor: Colors.white, ), splashColor: Colors.transparent, highlightColor: Colors.transparent, primarySwatch: Colors.red, primaryColor: Colors.black, indicatorColor: Colors.white, tabBarTheme: TabBarTheme(), ), /* initialRoute: '/', onGenerateRoute: RouteGenerator.generateRoute, */ builder: (context, child) { return ScrollConfiguration( behavior: MyBehavior(), child: child!, ); }, );

然后在需要引用的位置加入

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

调用的位置

AppLocalizations.of(context)!.home_top_foryou 至此,国际化就完成了

另外本地针对播放模块进行了优化,将代码拆分到videoplayer.dart文件.一来是方便代码阅读,而来可以作为子组件使用,其他的代码写得太冗余也在继续拆开,独立出来,各位感兴趣的可以关注项目的进展。

采用FutureBuilder对界面请求数据异步处理,当加载完成后才播放,效果更佳

代码如下:

return FutureBuilder<DTok>( future: videos, builder: (context, snapshot) { print(snapshot.connectionState); if (snapshot.connectionState == ConnectionState.waiting) { return loading; // return Column( // crossAxisAlignment: CrossAxisAlignment.center, // mainAxisAlignment: MainAxisAlignment.center, // children: [ // loading, // Visibility( // visible: snapshot.hasData, // child: PageView.builder( // controller: foryouController, // onPageChanged: (index) { // //when the video is changing, release the previous video instance. // //disposeVideo(); // setState(() {}); // }, // scrollDirection: Axis.vertical, // itemCount: snapshot.data!.itemList!.length, // itemBuilder: (context, index) { // var item = snapshot.data!.itemList![index]; // return Videoplayer( // item: item, // width: MediaQuery.of(context).size.width, // heigth: MediaQuery.of(context).size.height, // ); // }), // ) // ], // ); } else if (snapshot.connectionState == ConnectionState.done) { if (snapshot.hasError) { return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Error, Please restart your app agagin') ], ); } else if (snapshot.hasData) { try { return PageView.builder( controller: foryouController, onPageChanged: (index) { //when the video is changing, release the previous video instance. //disposeVideo(); //setState(() {}); }, scrollDirection: Axis.vertical, itemCount: snapshot.data!.itemList!.length, itemBuilder: (context, index) { var item = snapshot.data!.itemList![index]; return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); }); } catch (e) { return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, color: Colors.black, child: Center( child: Text( 'Error, Please restart your app again.', style: TextStyle(color: Colors.white), )), ); } } else { // empty data return loading; } } else { return Text('State: ${snapshot.connectionState}'); } });

这里可以看到当snapshot.connectionState == ConnectionState.waiting的时候请求的数据正在加载中,则显示加载的图标loading

当snapshot.connectionState == ConnectionState.done 时,此时数据已经加载完毕,但是加载完毕有可能也没有数据,所以需要判断不同的情况

当加载出现异常情况则显示异常的widget

if (snapshot.hasError) { return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Error, Please restart your app agagin') ], ); }

当if (snapshot.hasData)则说明有返回值,但是这个返回值不一定就是我们需要的数据,所以还需要try catch一下,保证呈现给用户的界面是正常的

try { return PageView.builder( controller: foryouController, onPageChanged: (index) { //when the video is changing, release the previous video instance. //disposeVideo(); //setState(() {}); }, scrollDirection: Axis.vertical, itemCount: snapshot.data!.itemList!.length, itemBuilder: (context, index) { var item = snapshot.data!.itemList![index]; return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); }); } catch (e) { return Container( width: MediaQuery.of(context).size.width, height: MediaQuery.of(context).size.height, color: Colors.black, child: Center( child: Text( 'Error, Please restart your app again.', style: TextStyle(color: Colors.white), )), ); } }

其他情况则返回加载状态,因为没有数据返回

另外加载videoplay的时候把width、heigth传入到下一个控件,这样好计算界面呈现的宽度与高度

return Videoplayer( item: item, width: MediaQuery.of(context).size.width, heigth: MediaQuery.of(context).size.height, ); 结语

请继续关注本博客,其他页面持续更新完成,源码地址:telsavideo, 欢迎fork和star,谢谢!!!

再次奉上演示地址:
前端地址:www.pgyer.com/dtok
后端服务器地址:47.95.209.198:8181/