meowUAManager.ets 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. import linysCapsuleButton from '../../components/buttons/linysCapsuleButton';
  2. import linysSymbol from '../../components/texts/linysSymbol';
  3. import linysTimeoutButton from '../../components/buttons/linysTimeoutButton';
  4. import { animation_default, capsule_bar_height, fontSize_Large, fontSize_Normal } from '../../hosts/bunch_of_defaults';
  5. import { bunch_of_settings } from '../../hosts/bunch_of_settings';
  6. import { bunch_of_user_agents, user_agent } from '../../hosts/bunch_of_user_agents';
  7. @Component
  8. struct meowUAManager {
  9. @StorageLink('bunch_of_user_agents') bunch_of_user_agents: bunch_of_user_agents = new bunch_of_user_agents();
  10. @StorageLink('bunch_of_settings') bunch_of_settings: bunch_of_settings = new bunch_of_settings(true);
  11. @StorageLink('universal_global_custom_ua_gateway') now_global_custom_UA: string = "";
  12. @StorageLink('user_agent_selected') @Watch('on_select') selected_index: number = -1; // -1 for system default
  13. @State default_pressing: boolean = false;
  14. // Colors
  15. @StorageProp('color_current_primary') color_current_primary: ResourceColor = $r('app.color.start_window_background');
  16. @StorageProp('color_current_secondary') color_current_secondary: ResourceColor = $r('app.color.block_color');
  17. @StorageProp('color_current_font') color_current_font: ResourceColor = $r('app.color.font_color_title');
  18. // Settings / Accessibility
  19. @StorageLink('preferred_hand_left_or_right') preferred_hand_left_or_right: string = 'right';
  20. build() {
  21. Column({ space: 2.5 }) {
  22. // linysText({
  23. // text: this.selected_index.toString() + ': ' + this.now_global_custom_UA
  24. // })
  25. Row() {
  26. Row() {
  27. Text($r('app.string.Settings_general_custom_ua_default'))// Title
  28. .fontColor(!this.default_pressing ? this.color_current_font : this.color_current_secondary)
  29. .fontWeight(!this.default_pressing ? FontWeight.Regular : FontWeight.Bold)
  30. .padding({ left: 2 })
  31. .fontSize(fontSize_Normal())
  32. .maxLines(1)
  33. .textOverflow({ overflow: TextOverflow.Ellipsis })
  34. .layoutWeight(1)
  35. .margin(10)
  36. .animation(animation_default())
  37. }
  38. .width("100%")
  39. .height("100%")
  40. .borderRadius(7)
  41. .backgroundColor(this.default_pressing ? this.color_current_font :
  42. this.color_current_primary)
  43. .animation(animation_default())
  44. } // Default
  45. .width("100%")
  46. .border({
  47. radius: 10,
  48. width: 2,
  49. color: -1 == this.selected_index ? this.color_current_font : "transparent",
  50. // color: "red"
  51. })
  52. .alignRules({
  53. middle: { anchor: "__container__", align: HorizontalAlign.Center },
  54. top: { anchor: "__container__", align: VerticalAlign.Top }
  55. })
  56. .onTouch((event) => {
  57. if (event.type == TouchType.Up) {
  58. this.default_pressing = false;
  59. // If touch ends
  60. } else {
  61. this.default_pressing = true;
  62. // If touching
  63. }
  64. })
  65. .onClick(() => {
  66. this.set_global_UA(-1);
  67. // Set UA
  68. })
  69. .height(46)
  70. .animation(animation_default())
  71. ForEach(this.bunch_of_user_agents.list_of_user_agents, (_user_agent: user_agent, key: number) => {
  72. meowUAButton({
  73. selected_index: this.selected_index,
  74. my_index: key,
  75. })
  76. })
  77. Row() {
  78. linysSymbol({ symbol_glyph_target: 'sys.symbol.plus_square' })
  79. .onClick(() => {
  80. this.add_new_custom_ua();
  81. })
  82. } // Add Button
  83. .justifyContent(this.preferred_hand_left_or_right == 'right' ? FlexAlign.End : FlexAlign.Start)
  84. .width("100%")
  85. .padding(5)
  86. }
  87. .padding(5)
  88. .borderRadius(13.5)
  89. .backgroundColor($r('sys.color.comp_background_tertiary'))
  90. .width("100%")
  91. .animation(animation_default())
  92. }
  93. async aboutToAppear() {
  94. let custom_user_agents = await this.bunch_of_settings.get('custom_user_agents') as string;
  95. this.bunch_of_user_agents.import_string(custom_user_agents);
  96. this.selected_index = await this.bunch_of_settings.get('custom_user_agents_selected_index') as number;
  97. // Get UA
  98. console.log("[Meow][meowUAManager] UA Manager READY");
  99. }
  100. on_select() {
  101. // console.log('meow ' + this.selected_index.toString())
  102. if (this.selected_index <= -1) {
  103. // If set back to default
  104. this.now_global_custom_UA = "";
  105. } else {
  106. this.now_global_custom_UA = this.bunch_of_user_agents.list_of_user_agents[this.selected_index].user_agent_content;
  107. }
  108. }
  109. set_global_UA(idx: number) {
  110. this.selected_index = -99;
  111. this.selected_index = idx;
  112. this.bunch_of_settings.set('custom_user_agents_selected_index', idx);
  113. }
  114. add_new_custom_ua() {
  115. this.bunch_of_user_agents.add_user_agent(new user_agent(new Date().toLocaleString(),
  116. "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0"));
  117. this.bunch_of_settings.set('custom_user_agents', this.bunch_of_user_agents.export_string());
  118. }
  119. }
  120. export default meowUAManager;
  121. @Component
  122. struct meowUAButton {
  123. @Link selected_index: number;
  124. @StorageLink('bunch_of_user_agents') bunch_of_user_agents: bunch_of_user_agents = new bunch_of_user_agents();
  125. @StorageLink('bunch_of_settings') bunch_of_settings: bunch_of_settings = new bunch_of_settings(true);
  126. @Prop my_index: number;
  127. @State my_ua: user_agent = this.bunch_of_user_agents.list_of_user_agents[this.my_index];
  128. @State my_label: string = this.my_ua.label;
  129. @State my_content: string = this.my_ua.user_agent_content;
  130. // Settings / Accessibility
  131. @StorageLink('preferred_hand_left_or_right') preferred_hand_left_or_right: string = 'right';
  132. // UI effects
  133. @State height_of_text_area: number = 42;
  134. @State is_pressing: boolean = false;
  135. @State is_editing: boolean = false;
  136. @State is_press_timing_ok: boolean = false;
  137. press_timing: number = 0;
  138. button_height_default: number = 42;
  139. // Edit inputs
  140. @State edit_label: string = this.my_label;
  141. @State edit_content: string = this.my_content;
  142. // Colors
  143. @StorageProp('color_current_primary') color_current_primary: ResourceColor = $r('app.color.start_window_background');
  144. @StorageProp('color_current_secondary') color_current_secondary: ResourceColor = $r('app.color.block_color');
  145. @StorageProp('color_current_font') color_current_font: ResourceColor = $r('app.color.font_color_title');
  146. build() {
  147. Column() {
  148. Column() {
  149. Row() {
  150. Text(this.my_label)// Title
  151. .fontColor(!this.is_pressing ? this.color_current_font : this.color_current_secondary)
  152. .fontWeight(!this.is_pressing ? FontWeight.Regular : FontWeight.Bold)
  153. .animation(animation_default())
  154. .padding({ left: 2 })
  155. .fontSize(fontSize_Normal())
  156. .maxLines(1)
  157. .textOverflow({ overflow: TextOverflow.Ellipsis })
  158. .layoutWeight(1)
  159. Scroll() {
  160. SymbolGlyph($r('sys.symbol.square_and_pencil'))
  161. .fontSize(fontSize_Large())
  162. .fontColor([this.color_current_secondary])
  163. } // Edit Icon
  164. .scrollable(ScrollDirection.Horizontal)
  165. .scrollBar(BarState.Off)
  166. .width(this.is_press_timing_ok ? 22 : 0)
  167. .margin({ left: this.is_press_timing_ok ? 10 : 0 })
  168. .animation(animation_default())
  169. } // UA button
  170. .borderRadius(this.is_editing ? { topLeft: 7, topRight: 7 } : 7)
  171. .backgroundColor(this.is_pressing ? this.color_current_font : this.color_current_primary)
  172. .animation(animation_default())
  173. .padding(10)
  174. .alignRules({
  175. middle: { anchor: "__container__", align: HorizontalAlign.Center },
  176. top: { anchor: "__container__", align: VerticalAlign.Top }
  177. })
  178. .onTouch((event) => {
  179. if (event.type == TouchType.Up) {
  180. this.is_pressing = false;
  181. // If touch ends
  182. } else {
  183. this.is_pressing = true;
  184. // If touching
  185. }
  186. })
  187. .onClick(() => {
  188. if (this.is_press_timing_ok) {
  189. this.is_editing = !this.is_editing;
  190. return;
  191. } // Toggle Edit Panel
  192. this.set_global_UA(this.my_index);
  193. // Set UA
  194. })
  195. .height(this.button_height_default)
  196. .onMouse((e) => {
  197. if (e.button == MouseButton.Right && e.action == MouseAction.Press) {
  198. // Right click
  199. this.is_editing = !this.is_editing;
  200. }
  201. })
  202. Scroll() {
  203. Column({ space: 10 }) {
  204. Row({ space: 10 }) {
  205. linysSymbol({ symbol_glyph_target: "sys.symbol.rename" })
  206. TextInput({ text: this.edit_label })
  207. .onChange((value) => {
  208. this.edit_label = value;
  209. })
  210. .fontWeight(FontWeight.Regular)
  211. .fontColor(this.color_current_font)
  212. .caretColor(this.color_current_font)
  213. .selectedBackgroundColor(this.color_current_font)
  214. .layoutWeight(1)
  215. .onSubmit(() => {
  216. this.save_changes();
  217. this.is_editing = false;
  218. })
  219. .height(capsule_bar_height())
  220. } // Edit label
  221. .width("100%")
  222. Row({ space: 10 }) {
  223. linysSymbol({ symbol_glyph_target: "sys.symbol.paperclip" })
  224. TextArea({ text: this.edit_content })
  225. .onChange((value) => {
  226. this.edit_content = value;
  227. })
  228. .fontWeight(FontWeight.Regular)
  229. .fontColor(this.color_current_font)
  230. .caretColor(this.color_current_font)
  231. .selectedBackgroundColor(this.color_current_font)
  232. .layoutWeight(1)
  233. .onSubmit(() => {
  234. this.save_changes();
  235. this.is_editing = false;
  236. })
  237. .onAreaChange((_o, n) => {
  238. this.height_of_text_area = n.height as number;
  239. })
  240. // .height(capsule_bar_height())
  241. } // Edit content
  242. .width("100%")
  243. .animation(animation_default())
  244. Row({ space: 10 }) {
  245. linysTimeoutButton({
  246. text: " 󰀁 ",
  247. onExecution: () => {
  248. this.delete_myself();
  249. }
  250. })
  251. linysCapsuleButton({ text: " 󰀻 " })
  252. .onClick(() => {
  253. this.save_changes();
  254. this.is_editing = false;
  255. })
  256. } // Buttons of operations
  257. .justifyContent(this.preferred_hand_left_or_right == 'right' ? FlexAlign.End : FlexAlign.Start)
  258. .animation(animation_default())
  259. .width("100%")
  260. }
  261. .padding({
  262. top: 6,
  263. left: 14,
  264. right: 14,
  265. bottom: 14
  266. })
  267. .backgroundColor(this.color_current_primary)
  268. .border({
  269. radius: { bottomLeft: 10, bottomRight: 10 }
  270. })
  271. } // Edit panel
  272. .height(!this.is_editing ? 0 : 108 + this.height_of_text_area)
  273. .visibility(this.is_editing ? Visibility.Visible : Visibility.None)
  274. .animation(animation_default())
  275. .scrollBar(BarState.Off)
  276. .nestedScroll({ scrollForward: NestedScrollMode.PARENT_FIRST, scrollBackward: NestedScrollMode.PARENT_FIRST })
  277. }
  278. .border({
  279. radius: 10,
  280. width: 2,
  281. color: this.my_index == this.selected_index ? this.color_current_font : "transparent"
  282. })
  283. }
  284. .width("100%")
  285. .animation(animation_default())
  286. .onAppear(() => {
  287. setInterval(() => {
  288. if (this.is_pressing) {
  289. this.press_timing += 1;
  290. } else {
  291. this.press_timing = 0;
  292. }
  293. this.is_press_timing_ok = this.press_timing > 16;
  294. // Count press time
  295. }, 10)
  296. })
  297. }
  298. set_global_UA(idx: number) {
  299. this.selected_index = -99;
  300. this.selected_index = idx;
  301. this.bunch_of_settings.set('custom_user_agents_selected_index', idx);
  302. }
  303. save_changes() {
  304. this.edit_content = this.edit_content.replaceAll("\n", "");
  305. this.my_label = this.edit_label;
  306. this.my_content = this.edit_content;
  307. this.bunch_of_user_agents.list_of_user_agents[this.my_index].label = this.edit_label;
  308. this.bunch_of_user_agents.list_of_user_agents[this.my_index].user_agent_content = this.edit_content;
  309. this.save_user_agents_to_settings();
  310. if (this.selected_index == this.my_index) {
  311. this.set_global_UA(this.my_index);
  312. }
  313. // This would refresh UI in other places
  314. this.bunch_of_user_agents.update_last_accessed();
  315. }
  316. delete_myself() {
  317. this.is_editing = false;
  318. this.bunch_of_user_agents.del_user_agent(this.my_index);
  319. if (this.selected_index == this.my_index) {
  320. this.selected_index = this.my_index - 1;
  321. } else {
  322. let previous_selected = this.selected_index;
  323. this.selected_index = -2;
  324. this.selected_index = Math.min(this.bunch_of_user_agents.list_of_user_agents.length - 1, previous_selected);
  325. // Refresh
  326. }
  327. this.save_user_agents_to_settings();
  328. }
  329. save_user_agents_to_settings() {
  330. console.log("[Meow][meowUAManager] Started to save custom user-agents to Settings!")
  331. this.bunch_of_settings.set('custom_user_agents', this.bunch_of_user_agents.export_string());
  332. }
  333. }