| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929 |
- import 'dart:convert';
- import 'dart:html';
- import 'dart:typed_data';
- import 'package:dio/dio.dart' as adio;
- import 'package:dio/dio.dart';
- import 'package:dotted_border/dotted_border.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter/services.dart';
- import 'package:flutter_svg/svg.dart';
- import 'package:get/get.dart';
- import 'package:link/view/preview.dart';
- import 'package:web_smooth_scroll/web_smooth_scroll.dart';
- import '../constants.dart';
- import '../utils/api.dart';
- import '../utils/http_utils.dart';
- import '../utils/size_fit.dart';
- import '../utils/storage.dart';
- import 'component/link_btn.dart';
- import 'component/link_step.dart';
- import 'component/toast.dart';
- import 'component/top_container.dart';
- import 'component/upload_file.dart';
- import 'component/web_image.dart';
- class EditLink extends StatefulWidget {
- const EditLink({Key? key}) : super(key: key);
- @override
- State<EditLink> createState() => _EditLinkState();
- }
- class _EditLinkState extends State<EditLink> {
- TextEditingController controller = TextEditingController();
- TextEditingController titleController = TextEditingController();
- TextEditingController descController = TextEditingController();
- FileUploadInputElement uploadInput = FileUploadInputElement();
- bool isLink = true;
- bool showError = false;
- Uint8List? chooseImage;
- String strLink = '';
- String strTitle = '';
- String strDesc = '';
- String imgUrl = '';
- bool isFirstEnter = true;
- var social;
- late List types;
- late ScrollController scrollController;
- @override
- void initState() {
- // TODO: implement initState
- scrollController = ScrollController();
- Map<String, dynamic> data = Get.parameters;
- social = jsonDecode(data['social']);
- types = social['types'];
- if (types[0] == 'LINK') {
- isLink = true;
- } else {
- isLink = false;
- }
- getDetail();
- super.initState();
- }
- @override
- dispose(){
- controller.dispose();
- titleController.dispose();
- descController.dispose();
- scrollController.dispose();
- super.dispose();
- }
- chooseFile() async {
- uploadInput.accept = '.png,.jpg,.jpeg';
- uploadInput.multiple = false;
- uploadInput.click();
- uploadInput.onChange.listen((e) {
- final files = uploadInput.files;
- if (files?.length == 1) {
- FileReader reader = FileReader();
- reader.onLoadEnd.listen((event) {
- setState(() {
- chooseImage = reader.result as Uint8List;
- });
- });
- reader.readAsArrayBuffer(files![0]);
- }
- });
- }
- Future getDetail() async {
- String id = Get.parameters['id']!;
- var data = await HttpUtils.get(Api.userSocials + '/$id');
- setState(() {
- if (data['type'] == 'LINK') {
- isLink = true;
- controller.text = data['user_url'];
- strLink = data['user_url'];
- } else {
- isLink = false;
- }
- strTitle = data['user_nick'];
- titleController.text = data['user_nick'];
- strDesc = data['description'];
- descController.text = data['description'];
- });
- }
- intro() {
- Color tapColor = kBtnColor;
- if (isLink) {
- if (strLink.isNotEmpty) {
- tapColor = const Color(0xFFA5A5AD);
- }
- } else {
- if (chooseImage != null) {
- tapColor = const Color(0xFFA5A5AD);
- }
- }
- return Container(
- color: showError ? const Color(0xFF002FFF) : Colors.transparent,
- padding: EdgeInsets.only(
- left: 20.px,
- right: 20.px,
- top: showError ? 12.px : 0,
- bottom: showError ? 12.px : 0),
- child: Column(
- children: [
- Row(
- children: [
- Container(
- width: 12.px,
- height: 12.px,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(6.px),
- border: Border.all(color: kThemeColor, width: 1.px)),
- child: Text(
- '1',
- style: TextStyle(
- color: kThemeColor,
- fontFamily: 'Link1',
- fontWeight: FontWeight.w800,
- fontSize: 8.px),
- ),
- ),
- SizedBox(
- width: 3.px,
- ),
- Text(
- '去『已选平台-我』找到「',
- style:
- TextStyle(color: const Color(0xFFA5A5AD), fontSize: 12.px),
- ),
- Text(
- isLink ? '分享-复制链接' : '我的二维码',
- style: TextStyle(
- color: const Color(0xFFA5A5AD),
- fontSize: 12.px,
- fontWeight: FontWeight.bold),
- ),
- Text(
- isLink ? '」' : '」保存',
- style:
- TextStyle(color: const Color(0xFFA5A5AD), fontSize: 12.px),
- ),
- ],
- ),
- SizedBox(
- height: 5.px,
- ),
- Row(
- children: [
- Container(
- width: 12.px,
- height: 12.px,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(6.px),
- border: Border.all(color: kThemeColor, width: 1.px)),
- child: Text(
- '2',
- style: TextStyle(
- color: kThemeColor,
- fontFamily: 'Link1',
- fontWeight: FontWeight.w800,
- fontSize: 8.px),
- ),
- ),
- SizedBox(
- width: 3.px,
- ),
- Text(
- '回到此处',
- style:
- TextStyle(color: const Color(0xFFA5A5AD), fontSize: 12.px),
- ),
- SizedBox(
- width: 3.px,
- ),
- if (!isLink && chooseImage == null)
- UploadFile(
- child: Text(
- '上传二维码',
- style: TextStyle(
- color: tapColor,
- fontSize: 12.px,
- fontWeight: FontWeight.bold),
- ),
- callback: (Uint8List file) {
- setState(() {
- chooseImage = file;
- showError = false;
- });
- },
- ),
- if (isLink || (chooseImage != null))
- GestureDetector(
- onTap: () {
- if (isLink) {
- if (strLink.isEmpty) {
- getClipData();
- }
- } else {
- if (chooseImage == null) {
- chooseFile();
- }
- }
- },
- child: Text(
- isLink ? '粘贴链接' : '上传二维码',
- style: TextStyle(
- color: tapColor,
- fontSize: 12.px,
- fontWeight: FontWeight.bold),
- ),
- )
- ],
- ),
- ],
- ),
- );
- }
- switchWarn() {
- return Container(
- alignment: Alignment.center,
- padding: EdgeInsets.only(top: 32.px, bottom: 32.px),
- child: Column(
- children: [
- SvgPicture.asset(
- 'assets/icons/question.svg',
- width: 48.px,
- height: 48.px,
- ),
- SizedBox(
- height: 12.px,
- ),
- Text(
- isLink
- ? '切换选择「二维码」\n将使现有「链接」不被展示\n确定要切换吗?'
- : '切换选择「链接」\n将使现有「二维码」不被展示\n确定要切换吗?',
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- fontSize: 16.px,
- fontWeight: FontWeight.bold),
- ),
- SizedBox(
- height: 16.px,
- ),
- AlertButton(
- title: '确定',
- isCancel: false,
- width: 220.px,
- height: 40.px,
- callback: () {
- Toast().hideHud();
- setState(() {
- showError = false;
- if (isLink) {
- strLink = '';
- isLink = false;
- } else {
- chooseImage = null;
- isLink = true;
- }
- });
- }),
- SizedBox(
- height: 24.px,
- ),
- AlertButton(
- title: '再想想',
- isCancel: true,
- width: 220.px,
- height: 40.px,
- callback: () {
- Toast().hideHud();
- }),
- ],
- ),
- );
- }
- switchType() {
- if (isLink && strLink.isNotEmpty) {
- Toast().showCustomHud(switchWarn(), context: context);
- return;
- }
- if (!isLink && chooseImage != null) {
- Toast().showCustomHud(switchWarn(), context: context);
- return;
- }
- setState(() {
- showError = false;
- isLink = !isLink;
- });
- }
- preview() {
- Toast().showText('长按图片识别或保存', context: context);
- showDialog(
- context: context,
- barrierDismissible: false,
- barrierColor: Colors.transparent,
- useSafeArea: false,
- builder: (BuildContext context) {
- return Preview(
- memory: chooseImage,
- );
- });
- }
- Future getClipData() async {
- await Clipboard.getData(Clipboard.kTextPlain).then((value) {
- if (value != null && value.text != null) {
- setState(() {
- strLink = value.text!;
- controller.text = strLink;
- });
- }
- });
- }
- content() {
- return Column(
- children: [
- SizedBox(
- height: 32.px,
- ),
- Container(
- width: 343.px,
- padding: EdgeInsets.all(20.px),
- margin: EdgeInsets.only(bottom: 20.px),
- decoration: BoxDecoration(
- color: const Color(0xFF2C2C2E),
- borderRadius: BorderRadius.circular(24.px)),
- child: GestureDetector(
- onTap: () {
- Toast().showInfoText('已添加的链接不能更改平台\n建议重新添加新链接\n并删除原有错误的链接',
- context: context);
- },
- child: Row(
- children: [
- Expanded(
- child: Text(
- '已选平台',
- style: TextStyle(
- color: kThemeColor,
- fontSize: 16.px,
- fontWeight: FontWeight.bold),
- )),
- // ClipRRect(
- // borderRadius: BorderRadius.circular(6.px),
- // child: social['logo'].length == 0
- // ? SvgPicture.asset(
- // 'assets/icons/other_link.svg',
- // width: 24.px,
- // height: 24.px,
- // )
- // : WebImage(
- // url: social['logo'], width: 24.px, height: 24.px),
- // ),
- social['logo'].length == 0
- ? ClipRRect(
- borderRadius: BorderRadius.circular(6.px),
- child: SvgPicture.asset(
- 'assets/icons/other_link.svg',
- width: 24.px,
- height: 24.px,
- ))
- : WebImage(
- url: social['logo'],
- width: 24.px,
- height: 24.px,
- borderRadius: 6.px,
- ),
- SizedBox(
- width: 8.px,
- ),
- Text(
- social['name'],
- style: TextStyle(
- color: const Color(0xFFA5A5AD), fontSize: 14.px),
- ),
- Image.asset(
- 'assets/images/arrow_right.png',
- width: 20.px,
- height: 20.px,
- )
- // SvgPicture.asset(
- // 'assets/icons/arrow_right.svg',
- // width: 20.px,
- // height: 20.px,
- // color: const Color(0xFFA5A5AD),
- // )
- ],
- )),
- ),
- Container(
- width: 343.px,
- padding: EdgeInsets.only(top: 20.px, bottom: 20.px),
- margin: EdgeInsets.only(bottom: 20.px),
- decoration: BoxDecoration(
- color: const Color(0xFF2C2C2E),
- borderRadius: BorderRadius.circular(24.px)),
- child: Column(
- children: [
- Row(
- children: [
- SizedBox(
- width: 20.px,
- ),
- Expanded(
- child: Text(
- '链接方式',
- style: TextStyle(
- color: kThemeColor,
- fontSize: 16.px,
- fontWeight: FontWeight.bold),
- )),
- Container(
- height: 28.px,
- // width: 98.px,
- decoration: BoxDecoration(
- color: const Color(0xFF131314),
- borderRadius: BorderRadius.circular(14.px)),
- child: Row(
- children: [
- Container(
- padding: EdgeInsets.only(left: 10.px, right: 10.px),
- height: 28.px,
- decoration: BoxDecoration(
- color: kThemeColor,
- borderRadius: BorderRadius.circular(14.px)),
- child: Row(
- children: [
- SvgPicture.asset(
- isLink
- ? 'assets/icons/link.svg'
- : 'assets/icons/qrcode.svg',
- width: 16.px,
- height: 16.px,
- color: const Color(0xFF131314),
- ),
- SizedBox(
- width: 2.px,
- ),
- Text(
- isLink ? '链接' : '二维码',
- style: TextStyle(
- color: const Color(0xFF131314),
- fontSize: 12.px),
- )
- ],
- ),
- ),
- if (types.length > 1)
- GestureDetector(
- onTap: () {
- switchType();
- },
- child: Container(
- alignment: Alignment.center,
- width: 36.px,
- height: 28.px,
- child: SvgPicture.asset(
- isLink
- ? 'assets/icons/qrcode.svg'
- : 'assets/icons/link.svg',
- width: 16.px,
- height: 16.px,
- color: const Color(0xFF74747A),
- ),
- ),
- )
- ],
- ),
- ),
- SizedBox(
- width: 20.px,
- )
- ],
- ),
- SizedBox(
- height: 8.px,
- ),
- intro(),
- // SizedBox(
- // height: 28.px,
- // ),
- SizedBox(
- height: 16.px,
- ),
- if (isLink)
- Row(
- children: [
- SizedBox(
- width: 20.px,
- ),
- Expanded(
- child: TextField(
- controller: controller,
- cursorColor: kBtnColor,
- onChanged: (value) {
- setState(() {
- strLink = value;
- showError = false;
- // keyword = value;
- });
- },
- style: TextStyle(
- color: Colors.white,
- fontSize: 14.px,
- fontFamily: 'Link1'),
- decoration: InputDecoration(
- border: InputBorder.none,
- hintText: '请输入链接',
- hintStyle: TextStyle(
- fontSize: 14.px, color: const Color(0xFF444447)),
- counterText: "",
- ),
- ),
- ),
- if (strLink.isEmpty)
- GestureDetector(
- onTap: () {
- getClipData();
- },
- child: SvgPicture.asset(
- 'assets/icons/copy_link.svg',
- width: 24.px,
- height: 24.px,
- color: kBtnColor,
- ),
- ),
- SizedBox(
- width: 20.px,
- ),
- ],
- ),
- if (!isLink)
- Stack(
- children: [
- DottedBorder(
- color: const Color(0xFF444447),
- borderType: BorderType.RRect,
- radius: Radius.circular(16.px),
- child: ClipRRect(
- borderRadius: BorderRadius.circular(16.px),
- child: Container(
- width: 303.px,
- alignment: Alignment.center,
- padding: EdgeInsets.only(top: 12.px, bottom: 12.px),
- child: chooseImage != null
- ? GestureDetector(
- onTap: () {
- preview();
- },
- child: Image.memory(
- chooseImage!,
- height: 120.px,
- ),
- )
- : UploadFile(
- // width: 120.px,
- // height: 120.px,
- child: SvgPicture.asset(
- 'assets/icons/upload_qrcode.svg',
- width: 120.px,
- height: 120.px,
- ),
- callback: (Uint8List file) {
- setState(() {
- chooseImage = file;
- showError = false;
- });
- },
- ),
- ),
- )),
- if (chooseImage != null)
- Positioned(
- right: 12.px,
- top: 12.px,
- child: UploadFile(
- // width: 68.px,
- // height: 28.px,
- child: Container(
- width: 68.px,
- height: 28.px,
- alignment: Alignment.center,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(14.px),
- color: const Color(0xBF131314)),
- child: Text(
- '重新上传',
- style: TextStyle(
- color: kBtnColor, fontSize: 12.px),
- )),
- callback: (Uint8List file) {
- setState(() {
- chooseImage = file;
- showError = false;
- });
- },
- ))
- // GestureDetector(
- // onTap: () {
- // chooseFile();
- // },
- // child: Container(
- // width: 68.px,
- // height: 28.px,
- // alignment: Alignment.center,
- // decoration: BoxDecoration(
- // borderRadius: BorderRadius.circular(14.px),
- // color: const Color(0xBF131314)),
- // child: Text(
- // '重新上传',
- // style: TextStyle(
- // color: kBtnColor, fontSize: 12.px),
- // )),
- // ))
- ],
- ),
- ],
- ),
- ),
- if ((isLink && strLink.isNotEmpty) || (!isLink && chooseImage != null))
- Container(
- width: 343.px,
- padding: EdgeInsets.all(20.px),
- margin: EdgeInsets.only(bottom: 20.px),
- decoration: BoxDecoration(
- color: const Color(0xFF2C2C2E),
- borderRadius: BorderRadius.circular(24.px)),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Text(
- '标题',
- style: TextStyle(
- color: kThemeColor,
- fontWeight: FontWeight.bold,
- fontSize: 16.px,
- height: 1.75),
- ),
- SizedBox(
- height: 8.px,
- ),
- SelectableText(
- '填写在我该平台上的用户名,不填将展示平台名称,如:',
- style: TextStyle(
- color: const Color(0xFFA5A5AD),
- fontSize: 12.px,
- height: 1.5),
- ),
- SizedBox(
- height: 16.px,
- ),
- TextField(
- cursorColor: kBtnColor,
- controller: titleController,
- onChanged: (value) {
- setState(() {
- // keyword = value;
- strTitle = value;
- });
- },
- style: TextStyle(color: Colors.white, fontSize: 14.px),
- decoration: InputDecoration(
- border: InputBorder.none,
- hintText: social['url_example'],
- hintStyle: TextStyle(
- fontSize: 14.px, color: const Color(0xFF444447)),
- counterText: "",
- ),
- ),
- Container(
- height: 1.px,
- color: const Color(0xFF444447),
- margin: EdgeInsets.only(top: 18.px, bottom: 18.px),
- ),
- Text(
- '描述',
- style: TextStyle(
- color: kThemeColor,
- fontWeight: FontWeight.bold,
- fontSize: 16.px,
- height: 1.75),
- ),
- SizedBox(
- height: 8.px,
- ),
- Text(
- '对以上内容的补充描述,如:',
- style: TextStyle(
- color: const Color(0xFFA5A5AD),
- fontSize: 12.px,
- height: 1.5),
- ),
- SizedBox(
- height: 16.px,
- ),
- TextField(
- cursorColor: kBtnColor,
- controller: descController,
- onChanged: (value) {
- setState(() {
- strDesc = value;
- // keyword = value;
- });
- },
- style: TextStyle(color: Colors.white, fontSize: 14.px),
- decoration: InputDecoration(
- border: InputBorder.none,
- hintText: social['description_example'],
- hintStyle: TextStyle(
- fontSize: 14.px, color: const Color(0xFF444447)),
- counterText: "",
- ),
- ),
- ],
- )),
- SizedBox(
- height: 162.px,
- )
- ],
- );
- }
- Future del() async {
- String id = Get.parameters['id']!;
- await HttpUtils.delete(Api.userSocials + '/$id');
- Get.back();
- }
- Future commit() async {
- String id = Get.parameters['id']!;
- if (isLink && strLink.isEmpty) {
- Toast().showInfoText('请粘贴链接地址后再提交\n或选择“稍后添加”', context: context);
- setState(() {
- showError = true;
- });
- return;
- }
- if (!isLink && chooseImage == null && imgUrl.isEmpty) {
- Toast().showInfoText('请上传二维码后再提交\n或选择“稍后添加”', context: context);
- setState(() {
- showError = true;
- });
- return;
- }
- Toast().showHud(context: context);
- if (isLink) {
- var data2 = await HttpUtils.put(Api.userSocials + '/$id', data: {
- 'user_url': strLink,
- 'description': strDesc,
- 'social_id': social['id'],
- 'social_name': social['id'].length == 0 ? social['name'] : '',
- 'type': 'LINK',
- 'user_nick': strTitle
- });
- } else {
- Map<String, dynamic> data = await HttpUtils.get(Api.ossFormUpload,
- params: {'type': 'AVATAR', 'file_ext': 'png'});
- Dio dio = Dio();
- Map<String, dynamic> map = data['fields'];
- map['file'] = await adio.MultipartFile.fromBytes(chooseImage!,
- filename: 'avatar.png');
- adio.FormData formData = adio.FormData.fromMap(map);
- adio.Response response =
- await dio.post(data['upload_url'], data: formData);
- var data2 = await HttpUtils.put(Api.userSocials + '/$id', data: {
- 'user_url': data['view_url'],
- 'description': strDesc,
- 'social_id': social['id'],
- 'social_name': social['id'].length == 0 ? social['name'] : '',
- 'type': 'QR',
- 'user_nick': strTitle
- });
- }
- Toast().hideHud();
- Get.back();
- }
- tapDelete() {
- Toast().showCustomHud(
- Container(
- alignment: Alignment.center,
- padding: EdgeInsets.only(top: 32.px, bottom: 32.px),
- child: Column(
- children: [
- Text(
- '删除此链接后,将无法恢复,\n确定要删除吗?',
- style: TextStyle(
- color: Colors.white,
- fontSize: 16.px,
- fontWeight: FontWeight.bold),
- ),
- SizedBox(
- height: 16.px,
- ),
- AlertButton(
- title: '确定,立即删除',
- isCancel: false,
- width: 220.px,
- height: 40.px,
- callback: () {
- Toast().hideHud();
- del();
- }),
- SizedBox(
- height: 24.px,
- ),
- AlertButton(
- title: '取消,再想想',
- isCancel: true,
- width: 220.px,
- height: 40.px,
- callback: () {
- Toast().hideHud();
- }),
- ],
- ),
- ),
- context: context);
- }
- @override
- Widget build(BuildContext context) {
- SizeFit.initialize(context);
- return Material(
- color: kBgColor,
- child: TopContainer(
- child: Stack(children: [
- Positioned(
- left: 0,
- top: 0,
- right: 0,
- height: MediaQuery.of(context).size.height,
- // bottom: 0,
- child: WebSmoothScroll(
- controller: scrollController,
- child: SingleChildScrollView(
- // physics: const NeverScrollableScrollPhysics(),
- controller: scrollController,
- child: content(),
- ))),
- Positioned(
- left: 0,
- right: 0,
- bottom: 0,
- child: Container(
- height: isFirstEnter ? 162.px : 140.px,
- decoration: const BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topCenter,
- end: Alignment.bottomCenter,
- colors: [
- Color(0x00131314),
- Color(0xFF131314),
- Color(0xFF131314),
- ])),
- child: Column(
- children: [
- SizedBox(
- height: 36.px,
- ),
- LinkButton(
- title: '保存修改',
- disable: false,
- isBlack: false,
- callback: () {
- commit();
- }),
- SizedBox(
- height: 30.px,
- ),
- GestureDetector(
- onTap: () {
- tapDelete();
- },
- child: Text(
- '删除已选账号',
- style: TextStyle(
- color: const Color(0xFF74747A), fontSize: 14.px),
- ),
- )
- ],
- ),
- ))
- ])));
- }
- }
|