phase3: badges 2.x->3.x migration (badgeStyle/animation), SearchBar/onPrimary fixes. 596->580
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
import 'package:flutter_wisetronic/widgets/general/breadcrumbs.dart';
|
import 'package:flutter_wisetronic/widgets/general/breadcrumbs.dart';
|
||||||
import 'package:flutter_wisetronic/widgets/general/navigationbar.dart';
|
import 'package:flutter_wisetronic/widgets/general/navigationbar.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter_wisetronic/pages/product_detail_page.dart';
|
import 'package:flutter_wisetronic/pages/product_detail_page.dart';
|
||||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_product_item.dart';
|
import 'package:flutter_wisetronic/widgets/desktop/desktop_product_item.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
|
|
||||||
import '../../constants.dart';
|
import '../../constants.dart';
|
||||||
import '../../events/eventbus.dart';
|
import '../../events/eventbus.dart';
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ class ShopProductsState extends State<ShopProducts> {
|
|||||||
fontSize: 11.0,
|
fontSize: 11.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
animationType: BadgeAnimationType.scale,
|
animation: BadgeAnimation.scale(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -120,13 +120,12 @@ class AddRemoveButtonState extends State<AddRemoveButton> {
|
|||||||
fontSize: 17.0,
|
fontSize: 17.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.all(10),
|
|
||||||
position: BadgePosition.topEnd(top: -15, end: -10),
|
position: BadgePosition.topEnd(top: -15, end: -10),
|
||||||
badgeColor: Colors.lightBlueAccent,
|
badgeStyle: BadgeStyle(badgeColor: Colors.lightBlueAccent, padding: EdgeInsets.all(10)),
|
||||||
child: ElevatedButton.icon(
|
child: ElevatedButton.icon(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor: Colors.redAccent,
|
backgroundColor: Colors.redAccent,
|
||||||
onPrimary: Colors.white,
|
foregroundColor: Colors.white,
|
||||||
padding: EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
padding: EdgeInsets.only(left: 32, right: 32, top: 20, bottom: 20),
|
||||||
elevation: 2.0,
|
elevation: 2.0,
|
||||||
shape: new RoundedRectangleBorder(
|
shape: new RoundedRectangleBorder(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
|
|
||||||
import '../../events/eventbus.dart';
|
import '../../events/eventbus.dart';
|
||||||
import '../../events/events.dart';
|
import '../../events/events.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
|
|
||||||
import '../../events/eventbus.dart';
|
import '../../events/eventbus.dart';
|
||||||
import '../../events/events.dart';
|
import '../../events/events.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import '../general/search_bar.dart';
|
import '../general/search_bar.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart' hide SearchBar;
|
||||||
|
|
||||||
import '../../events/eventbus.dart';
|
import '../../events/eventbus.dart';
|
||||||
import '../../events/events.dart';
|
import '../../events/events.dart';
|
||||||
|
|||||||
@@ -449,7 +449,7 @@ class ShopState extends State<Shop>
|
|||||||
'${_business.commentsCount}',
|
'${_business.commentsCount}',
|
||||||
style: TextStyle(color: Colors.white, fontSize: 11.0),
|
style: TextStyle(color: Colors.white, fontSize: 11.0),
|
||||||
),
|
),
|
||||||
badgeColor: Colors.lightBlueAccent,
|
badgeStyle: BadgeStyle(badgeColor: Colors.lightBlueAccent),
|
||||||
child: Text(S.of(context).comments),
|
child: Text(S.of(context).comments),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -1188,7 +1188,7 @@ class ShopState extends State<Shop>
|
|||||||
fontSize: 11.0,
|
fontSize: 11.0,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
animationType: BadgeAnimationType.scale,
|
animation: BadgeAnimation.scale(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
80
tools/badge_migrate.py
Normal file
80
tools/badge_migrate.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""badge_migrate.py — 把 badges 2.x 用法迁移到 3.x。
|
||||||
|
- animationType: BadgeAnimationType.X -> animation: BadgeAnimation.X()
|
||||||
|
- Badge(... badgeColor: C, padding: P ...) -> Badge(... badgeStyle: BadgeStyle(badgeColor: C, padding: P) ...)
|
||||||
|
"""
|
||||||
|
import re, glob
|
||||||
|
|
||||||
|
def find_calls(text, name):
|
||||||
|
calls=[]
|
||||||
|
for m in re.finditer(r'\b'+name+r'\s*\(', text):
|
||||||
|
if m.start()>0 and (text[m.start()-1].isalnum() or text[m.start()-1]=='_'):
|
||||||
|
continue # 跳过 BadgeStyle/BadgeAnimation 等同名前缀
|
||||||
|
i=m.end()-1; depth=0; j=i
|
||||||
|
while j<len(text):
|
||||||
|
c=text[j]
|
||||||
|
if c=='(' : depth+=1
|
||||||
|
elif c==')':
|
||||||
|
depth-=1
|
||||||
|
if depth==0: break
|
||||||
|
j+=1
|
||||||
|
if j<len(text):
|
||||||
|
calls.append((m.start(), j, text[i+1:j])) # inner 不含外层括号
|
||||||
|
return calls
|
||||||
|
|
||||||
|
def extract_param(inner, key):
|
||||||
|
"""从 inner 中提取 'key: value' 的 value(value 含平衡括号,到顶层逗号)。返回 (value, start, end)。"""
|
||||||
|
for m in re.finditer(r'\b'+key+r'\s*:\s*', inner):
|
||||||
|
start=m.end(); depth=0; j=start
|
||||||
|
while j<len(inner):
|
||||||
|
c=inner[j]
|
||||||
|
if c in '([{': depth+=1
|
||||||
|
elif c in ')]}':
|
||||||
|
if depth==0: break
|
||||||
|
depth-=1
|
||||||
|
elif c==',' and depth==0: break
|
||||||
|
j+=1
|
||||||
|
val=inner[start:j].strip().rstrip(',').strip()
|
||||||
|
return val, m.start(), j
|
||||||
|
return None, None, None
|
||||||
|
|
||||||
|
changed_files=0
|
||||||
|
for path in glob.glob('lib/**/*.dart', recursive=True):
|
||||||
|
t=open(path).read()
|
||||||
|
if 'Badge(' not in t: continue
|
||||||
|
orig=t
|
||||||
|
# 1) animationType: BadgeAnimationType.X -> animation: BadgeAnimation.X()
|
||||||
|
t=re.sub(r'animationType:\s*BadgeAnimationType\.(\w+)', r'animation: BadgeAnimation.\1()', t)
|
||||||
|
# 2) 合并 badgeColor + padding -> badgeStyle(从后往前处理避免偏移)
|
||||||
|
while True:
|
||||||
|
calls=find_calls(t, 'Badge')
|
||||||
|
did=False
|
||||||
|
for s,e,inner in reversed(calls):
|
||||||
|
bc,_,_=extract_param(inner,'badgeColor')
|
||||||
|
pd,_,_=extract_param(inner,'padding')
|
||||||
|
if not (bc or pd): continue
|
||||||
|
new_inner=inner
|
||||||
|
parts=[]
|
||||||
|
if bc:
|
||||||
|
v,vs,ve=extract_param(new_inner,'badgeColor')
|
||||||
|
# 删除该参数(含尾随逗号)
|
||||||
|
seg=new_inner[vs:ve]
|
||||||
|
after=new_inner[ve:]
|
||||||
|
if after.lstrip().startswith(','): after=after.lstrip()[1:]
|
||||||
|
new_inner=new_inner[:vs]+after
|
||||||
|
parts.append('badgeColor: '+bc)
|
||||||
|
if pd:
|
||||||
|
v,vs,ve=extract_param(new_inner,'padding')
|
||||||
|
seg=new_inner[vs:ve]
|
||||||
|
after=new_inner[ve:]
|
||||||
|
if after.lstrip().startswith(','): after=after.lstrip()[1:]
|
||||||
|
new_inner=new_inner[:vs]+after
|
||||||
|
parts.append('padding: '+pd)
|
||||||
|
badge_style='\n badgeStyle: BadgeStyle('+', '.join(parts)+'),'
|
||||||
|
new_inner=badge_style+new_inner
|
||||||
|
t=t[:s]+'Badge('+new_inner+')'+t[e+1:]
|
||||||
|
did=True; break
|
||||||
|
if not did: break
|
||||||
|
if t!=orig:
|
||||||
|
open(path,'w').write(t); changed_files+=1; print('migrated', path)
|
||||||
|
print('done, files:', changed_files)
|
||||||
Reference in New Issue
Block a user