AboutPage.ets 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import TitleBar from '../view/TitleBar'
  2. import { router } from '@kit.ArkUI'
  3. import { CommonConstants } from '../common/constants/CommonConstants'
  4. import { AppUtil, DeviceUtil, DisplayUtil, ToastUtil } from '@pura/harmony-utils'
  5. import { Utility } from '../common/util/Utility'
  6. import { common, ConfigurationConstant } from '@kit.AbilityKit'
  7. import { BreakpointTypeEnum } from '../common/util/BreakpointSystem'
  8. import { resourceManager } from '@kit.LocalizationKit'
  9. import { PreferencesUtil } from '@pura/harmony-utils'
  10. import { hilog } from '@kit.PerformanceAnalysisKit'
  11. import { BusinessError } from '@kit.BasicServicesKit'
  12. @Preview
  13. // @Entry
  14. @Component
  15. export struct AboutPage{
  16. @Consume isShowDrawer: boolean;
  17. @Consume offsetX: number;
  18. @State isDarkMode: boolean = false
  19. @StorageProp('currentColorMode') @Watch('onColorModeChange') currentMode: number =
  20. ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT;
  21. /** 当前断点类型(如大屏/小屏) */
  22. @StorageProp('currentBreakpoint') currentBreakpoint: string = BreakpointTypeEnum.MD;
  23. @StorageProp('themeColor') themeColor: string = CommonConstants.DEFAULT_THEME_COLOR;
  24. onColorModeChange() {
  25. this.isDarkMode = this.currentMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK
  26. }
  27. @State verName:string = ''
  28. @State appName:string = ''
  29. @StorageProp('topRectHeight') topRectHeight: number = px2vp(AppUtil.getStatusBarHeight());
  30. // 组件生命周期
  31. aboutToAppear() {
  32. // Utility.disableFullScreen()
  33. this.topRectHeight = px2vp(AppUtil.getStatusBarHeight());
  34. this.verName = AppUtil.getVersionName()
  35. Utility.getAppName(getContext(this)).then((appName:string)=>{
  36. this.appName = appName
  37. })
  38. let themeColor = PreferencesUtil.getStringSync('THEME_COLOR', CommonConstants.DEFAULT_THEME_COLOR);
  39. AppStorage.setOrCreate('themeColor', themeColor);
  40. this.themeColor = themeColor;
  41. this.onColorModeChange()
  42. console.info('LifeCycleComponent aboutToAppear');
  43. }
  44. // 组件生命周期
  45. aboutToDisappear() {
  46. console.info('LifeCycleComponent aboutToDisappear');
  47. }
  48. // 工具函数:hex转hsl、hsl转hex、生成渐变色
  49. hexToHsl(hex: string): [number, number, number] {
  50. hex = hex.replace('#', '');
  51. let r = parseInt(hex.substring(0,2), 16) / 255;
  52. let g = parseInt(hex.substring(2,4), 16) / 255;
  53. let b = parseInt(hex.substring(4,6), 16) / 255;
  54. let max = Math.max(r, g, b), min = Math.min(r, g, b);
  55. let h = 0, s = 0, l = (max + min) / 2;
  56. if(max !== min){
  57. let d = max - min;
  58. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  59. switch(max){
  60. case r: h = (g - b) / d + (g < b ? 6 : 0); break;
  61. case g: h = (b - r) / d + 2; break;
  62. case b: h = (r - g) / d + 4; break;
  63. }
  64. h = h * 60;
  65. }
  66. return [h, s, l];
  67. }
  68. hslToHex(h: number, s: number, l: number): string {
  69. let c = (1 - Math.abs(2 * l - 1)) * s;
  70. let x = c * (1 - Math.abs((h / 60) % 2 - 1));
  71. let m = l - c/2;
  72. let r=0, g=0, b=0;
  73. if (0 <= h && h < 60) { r = c; g = x; b = 0; }
  74. else if (60 <= h && h < 120) { r = x; g = c; b = 0; }
  75. else if (120 <= h && h < 180) { r = 0; g = c; b = x; }
  76. else if (180 <= h && h < 240) { r = 0; g = x; b = c; }
  77. else if (240 <= h && h < 300) { r = x; g = 0; b = c; }
  78. else if (300 <= h && h < 360) { r = c; g = 0; b = x; }
  79. let toHex = (v: number) => Math.round((v + m) * 255).toString(16).padStart(2, '0');
  80. return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
  81. }
  82. getGradientColor(themeColor: string, offset: number = 40): string {
  83. let hsl = this.hexToHsl(themeColor);
  84. let h = hsl[0];
  85. let s = hsl[1];
  86. let l = hsl[2];
  87. h = (h + offset) % 360;
  88. return this.hslToHex(h, s, l);
  89. }
  90. build() {
  91. Column(){
  92. // 顶部安全区和自定义标题栏
  93. Column() {
  94. // 顶部安全区
  95. Blank()
  96. .height(this.topRectHeight)
  97. .backgroundColor(this.isDarkMode?$r('app.color.title_bar_bg'):this.themeColor)
  98. .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
  99. // 自定义标题栏(Stack实现绝对居中)
  100. Stack() {
  101. // 居中标题
  102. Text('关于我们')
  103. .fontSize(18)
  104. .fontColor(Color.White)
  105. .align(Alignment.Center)
  106. // 左右按钮
  107. Row() {
  108. Image($r('app.media.menu'))
  109. .width(26)
  110. .height(26)
  111. .margin({ left: 12, right: 8 })
  112. .onClick(() => {
  113. animateTo({ duration: 555 }, () => {
  114. // 动画闭包内控制Image组件的出现和消失
  115. this.isShowDrawer = !this.isShowDrawer
  116. this.offsetX = 0
  117. })
  118. })
  119. Blank().flexGrow(1)
  120. Blank().width(32)
  121. }
  122. .height(48)
  123. .width('100%')
  124. .alignItems(VerticalAlign.Center)
  125. }
  126. .height(48)
  127. .width('100%')
  128. .backgroundColor(this.isDarkMode?$r('app.color.title_bar_bg'):this.themeColor)
  129. }
  130. Scroll(){
  131. Column(){
  132. Image($r('app.media.icon'))
  133. .width(120)
  134. .height(120)
  135. .borderRadius('100%')
  136. .clip(true)
  137. Text(this.appName+'V:'+this.verName)
  138. .fontColor(this.isDarkMode ? Color.White : Color.Black)
  139. .fontWeight(480)
  140. .fontSize(17)
  141. .margin({top:20,bottom:10})
  142. Text(CommonConstants.ICP_NO)
  143. .fontColor(this.isDarkMode ? Color.White : Color.Black)
  144. .fontWeight(480)
  145. .decoration({ type: TextDecorationType.Underline, color: this.isDarkMode ? Color.White : Color.Black })
  146. .fontSize(17)
  147. .margin({top:10,bottom:10})
  148. .onClick(()=>{
  149. let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  150. context.openLink(CommonConstants.ICP_URL, {})
  151. })
  152. Button('用户协议', { type: ButtonType.Capsule, stateEffect: false })
  153. .width(this.currentBreakpoint !== BreakpointTypeEnum.SM?'25%':'60%')
  154. .height(55)
  155. .margin({top:10,bottom:10})
  156. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
  157. .stateEffect(true)
  158. .backgroundColor(this.themeColor)
  159. .onClick(()=>{
  160. router.pushUrl({
  161. url: 'pages/WebIndex',
  162. params: { titleName: '用户协议', webUrl: CommonConstants.NEW_DUTY }
  163. });
  164. })
  165. Button('隐私政策', { type: ButtonType.Capsule, stateEffect: false })
  166. .width(this.currentBreakpoint !== BreakpointTypeEnum.SM?'25%':'60%')
  167. .height(55)
  168. .margin({top:10,bottom:10})
  169. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
  170. .stateEffect(true)
  171. .backgroundColor(this.themeColor)
  172. .onClick(()=>{
  173. router.pushUrl({
  174. url: 'pages/WebIndex',
  175. params: { titleName: '隐私政策', webUrl: CommonConstants.NEW_YS_HW }
  176. });
  177. })
  178. Button('粉丝QQ群', { type: ButtonType.Capsule, stateEffect: false })
  179. .width(this.currentBreakpoint !== BreakpointTypeEnum.SM?'25%':'60%')
  180. .height(55)
  181. .margin({top:10,bottom:20})
  182. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
  183. .stateEffect(true)
  184. .backgroundColor(this.themeColor)
  185. .onClick(()=>{
  186. ToastUtil.showToast('复制群号成功!')
  187. Utility.copyText('685109858')
  188. const qqUrl = `mqqapi://card/show_pslcard?src_type=internal&version=1&uin=${CommonConstants.QQ_GROUP}&card_type=group&source=external`;
  189. let context = this.getUIContext().getHostContext() as common.UIAbilityContext;
  190. context.openLink(qqUrl, {})
  191. })
  192. Button('用户反馈', { type: ButtonType.Capsule, stateEffect: false })
  193. .width(this.currentBreakpoint !== BreakpointTypeEnum.SM?'25%':'60%')
  194. .height(55)
  195. .stateEffect(true)
  196. .margin({bottom:20})
  197. .clickEffect({level:ClickEffectLevel.LIGHT, scale: 0.7})
  198. .backgroundColor(this.themeColor)
  199. .onClick(()=>{
  200. AlertDialog.show({
  201. title:'发送邮件',
  202. message:'感谢你的支持,如果有什么不支持的格式不能播放请反馈给我们修复,谢谢!有建议和反馈的请邮件联系我们:'+CommonConstants.CONTACT_MAIL,
  203. autoCancel:true,
  204. alignment:DialogAlignment.Center,
  205. offset:{dx:0,dy:-20},
  206. confirm:{
  207. value:'确定',
  208. fontColor:Color.White,
  209. backgroundColor:$r('app.color.title_bar_bg'),
  210. action:()=>{
  211. ToastUtil.showToast('复制邮件地址成功!')
  212. Utility.copyText(CommonConstants.CONTACT_MAIL)
  213. }
  214. }
  215. })
  216. })
  217. }
  218. .justifyContent(FlexAlign.Start)
  219. .width('100%')
  220. }
  221. .layoutWeight(1)
  222. .transition(TransitionEffect.move(TransitionEdge.BOTTOM)
  223. .animation({ duration: 380, curve: Curve.Ease,delay:50 }))
  224. .backgroundColor(this.isDarkMode?Color.Black:this.themeColor)
  225. .linearGradient(!this.isDarkMode ? {colors:[[this.themeColor, 0.0], [this.getGradientColor(this.themeColor, 40), 0.6]]} : undefined)
  226. }
  227. .layoutWeight(1)
  228. .width('100%')
  229. .height('100%')
  230. }
  231. }