add deb builder script.
This commit is contained in:
@@ -44,3 +44,4 @@ app.*.map.json
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
pubspec.lock
|
||||
deb_builder/
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2023, dx8917312@gmail.com
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
flutter packages pub get
|
||||
|
||||
VERSION=$(dart version.dart)
|
||||
|
||||
flutter clean
|
||||
|
||||
flutter build linux
|
||||
|
||||
if [ -e deb_builder ]; then
|
||||
rm -rf deb_builder
|
||||
fi
|
||||
|
||||
|
||||
mkdir "deb_builder"
|
||||
|
||||
cp -r debian deb_builder/DEBIAN
|
||||
chmod -R 755 deb_builder/DEBIAN
|
||||
|
||||
cp LICENSE deb_builder/DEBIAN/copyright
|
||||
|
||||
echo "设置版本号为: $VERSION"
|
||||
|
||||
echo Version: "$VERSION" >> deb_builder/DEBIAN/control
|
||||
|
||||
mkdir -p deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/
|
||||
|
||||
cp -r dde_package_info/* deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/
|
||||
|
||||
ARCH="x64"
|
||||
|
||||
if [[ $(uname -m) == aarch64 ]]; then
|
||||
ARCH="arm64"
|
||||
sed -i "s/amd64/$ARCH/g" deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/info
|
||||
sed -i "s/amd64/$ARCH/g" deb_builder/DEBIAN/control
|
||||
fi
|
||||
|
||||
cp -r build/linux/"$ARCH"/release/bundle deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/files
|
||||
|
||||
mkdir -p deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/entries/icons/hicolor/512x512/apps/
|
||||
|
||||
cp logo.png deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/entries/icons/hicolor/512x512/apps/dde_qrcode_detector.png
|
||||
|
||||
sed -i "s/VERSION/$VERSION/g" deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/info
|
||||
|
||||
sed -i "s/VERSION/$VERSION/g" deb_builder/opt/apps/com.debuggerx.dde-qrcode-detector/entries/applications/com.debuggerx.dde-qrcode-detector.desktop
|
||||
|
||||
echo "开始打包 $ARCH deb"
|
||||
|
||||
fakeroot dpkg-deb -b deb_builder
|
||||
|
||||
if [[ $ARCH == "x64" ]]; then
|
||||
ARCH="amd64"
|
||||
fi
|
||||
|
||||
mv deb_builder.deb com.debuggerx.dde-qrcode-detector_"$VERSION"_"$ARCH".deb
|
||||
|
||||
echo "打包完成!"
|
||||
@@ -0,0 +1,10 @@
|
||||
[Desktop Entry]
|
||||
Categories=Utility;
|
||||
Comment=专为 DDE 桌面环境打造的屏幕二维码识别工具,使用 Flutter 构建。
|
||||
Exec=/opt/apps/com.debuggerx.dde-qrcode-detector/files/dde_qrcode_detector
|
||||
Icon=dde_qrcode_detector
|
||||
Name=DDE Qrcode Detector
|
||||
Name[zh_CN]=DDE二维码识别
|
||||
Type=Application
|
||||
Version=VERSION
|
||||
X-Deepin-Vendor=user-custom
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"appid": "com.debuggerx.dde-qrcode-detector",
|
||||
"name": "dde-qrcode-detector",
|
||||
"version": "VERSION",
|
||||
"arch": ["amd64"],
|
||||
"permissions": {
|
||||
"autostart": false,
|
||||
"notification": false,
|
||||
"trayicon": false,
|
||||
"clipboard": true,
|
||||
"account": false,
|
||||
"bluetooth": false,
|
||||
"camera": false,
|
||||
"audio_record": false,
|
||||
"installed_apps": false
|
||||
}
|
||||
}
|
||||
Vendored
Vendored
+15
@@ -0,0 +1,15 @@
|
||||
Source: dde-qrcode-detector
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Maintainer: DebuggerX <dx8913712@163.com>
|
||||
Build-Depends:
|
||||
clang,
|
||||
cmake,
|
||||
libgtk-3-dev,
|
||||
ninja-build,
|
||||
libzbar-dev,
|
||||
Homepage: https://github.com/debuggerx01/dde_qrcode_detector
|
||||
Package: com.debuggerx.dde-qrcode-detector
|
||||
Architecture: amd64
|
||||
Depends: libzbar0
|
||||
Description: 专为 DDE 桌面环境打造的屏幕二维码识别工具,使用 Flutter 构建。
|
||||
+82
-29
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:dde_qrcode_detector/utils.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@@ -65,6 +66,7 @@ enum Status {
|
||||
scan,
|
||||
found,
|
||||
notFound,
|
||||
finish,
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
@@ -85,15 +87,29 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
});
|
||||
WindowManager.instance.focus();
|
||||
WindowManager.instance.grabKeyboard();
|
||||
Future.delayed(const Duration(seconds: 1), () {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (context.mounted) {
|
||||
setState(() {
|
||||
status = Status.scan;
|
||||
});
|
||||
compute(scan, null).then((codes) {
|
||||
}
|
||||
compute(scan, null).then((result) {
|
||||
if (context.mounted) {
|
||||
setState(() {
|
||||
codes = codes;
|
||||
codes = result;
|
||||
status = codes.isEmpty ? Status.notFound : Status.found;
|
||||
});
|
||||
}
|
||||
Future.delayed(const Duration(seconds: 3), () {
|
||||
if (status == Status.notFound) {
|
||||
exit(0);
|
||||
}
|
||||
if (context.mounted) {
|
||||
setState(() {
|
||||
status = Status.finish;
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
super.initState();
|
||||
@@ -102,62 +118,91 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
static Future<List<ZBar.CodeInfo>> scan(dynamic _) async {
|
||||
var imagePath = '/tmp/${DateTime.now().toIso8601String()}.png';
|
||||
Process.runSync('scrot', [imagePath]);
|
||||
return ZBar.scan(imagePath);
|
||||
var result = ZBar.scan(imagePath);
|
||||
File(imagePath).delete();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
late Rect rect;
|
||||
if (pos != null) {
|
||||
rect = Rect.fromPoints(
|
||||
Offset(pos!.bottomLeft.x, pos!.bottomLeft.y),
|
||||
Offset(pos!.topRight.x, pos!.topRight.y),
|
||||
);
|
||||
rect = rect.translate(-currentWindowPos.dx, -currentWindowPos.dy);
|
||||
}
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
if ([Status.found, Status.notFound].contains(status)) {
|
||||
if ([
|
||||
Status.found,
|
||||
Status.notFound,
|
||||
Status.finish,
|
||||
].contains(status)) {
|
||||
exit(0);
|
||||
}
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(),
|
||||
backgroundColor: status == Status.standBy
|
||||
? Colors.transparent
|
||||
: Colors.black12.withOpacity(
|
||||
status == Status.scan ? 0.4 : 0.2,
|
||||
),
|
||||
body: Stack(
|
||||
fit: StackFit.expand,
|
||||
children: [
|
||||
if (status == Status.scan)
|
||||
if (![Status.standBy, Status.finish].contains(status))
|
||||
Center(
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
color: Colors.grey.shade700.withOpacity(0.9),
|
||||
),
|
||||
child: RepaintBoundary(
|
||||
width: 460,
|
||||
height: 360,
|
||||
child: Center(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
RepaintBoundary(
|
||||
child: Image.asset(
|
||||
'assets/doubt.gif',
|
||||
{
|
||||
Status.scan: 'assets/doubt.gif',
|
||||
Status.found: 'assets/ok.gif',
|
||||
Status.notFound: 'assets/no.gif',
|
||||
}[status]!,
|
||||
width: 200,
|
||||
height: 200,
|
||||
fit: BoxFit.fitHeight,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
{
|
||||
Status.scan: '小浣熊正在努力寻找二维码~',
|
||||
Status.found: '小浣熊成功找到${codes.length}个二维码!',
|
||||
Status.notFound: '小浣熊找了一圈,啥也没发现……',
|
||||
}[status]!,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 28,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (status == Status.found)
|
||||
Positioned(
|
||||
left: rect.left - rect.width / 2,
|
||||
top: rect.top - rect.height / 2,
|
||||
...codes.map(
|
||||
(code) {
|
||||
var centerAndSize = getCenterAndSizeOfPoints(code.points);
|
||||
var center = centerAndSize.center - currentWindowPos;
|
||||
var size = max(centerAndSize.size, 300);
|
||||
return Positioned(
|
||||
left: center.dx - size / 2,
|
||||
top: center.dy - size / 2,
|
||||
child: Container(
|
||||
width: rect.width * 2,
|
||||
height: rect.height * 2,
|
||||
width: size.toDouble(),
|
||||
height: size.toDouble(),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(
|
||||
max(rect.width, rect.height),
|
||||
),
|
||||
borderRadius: BorderRadius.circular(size / 2),
|
||||
color: Colors.black38.withOpacity(.6),
|
||||
),
|
||||
padding: EdgeInsets.all(size / 6),
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
@@ -168,10 +213,12 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
AutoSizeText(
|
||||
content?.text ?? '',
|
||||
Flexible(
|
||||
child: AutoSizeText(
|
||||
code.content.split('').join('\u{200B}'),
|
||||
style: const TextStyle(
|
||||
fontSize: 28,
|
||||
color: Colors.white,
|
||||
@@ -179,23 +226,27 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
minFontSize: 16,
|
||||
maxFontSize: 46,
|
||||
),
|
||||
),
|
||||
SizedBox(height: size / 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
FilledButton(
|
||||
onPressed: () {
|
||||
Clipboard.setData(
|
||||
ClipboardData(text: content?.text),
|
||||
ClipboardData(text: code.content),
|
||||
);
|
||||
exit(0);
|
||||
},
|
||||
child: const Text(
|
||||
'复制',
|
||||
style: TextStyle(fontSize: 28),
|
||||
),
|
||||
),
|
||||
SizedBox(width: size / 20),
|
||||
FilledButton(
|
||||
onPressed: () async {
|
||||
var url = content?.text ?? '';
|
||||
var url = code.content;
|
||||
if (await canLaunchUrlString(url)) {
|
||||
launchUrlString(url).then((value) {
|
||||
exit(0);
|
||||
@@ -213,6 +264,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:zbar_scan_plugin/zbar_scan_plugin.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'dart:math';
|
||||
|
||||
class CenterAndSize {
|
||||
final Offset center;
|
||||
final double size;
|
||||
|
||||
CenterAndSize({
|
||||
required this.center,
|
||||
required this.size,
|
||||
});
|
||||
}
|
||||
|
||||
CenterAndSize getCenterAndSizeOfPoints(List<PointInfo> points) {
|
||||
if (points.isEmpty) {
|
||||
return CenterAndSize(
|
||||
center: Offset.zero,
|
||||
size: 0,
|
||||
);
|
||||
}
|
||||
var center = Offset(
|
||||
points.map((p) => p.x).average,
|
||||
points.map((p) => p.y).average,
|
||||
);
|
||||
|
||||
var size = sqrt(
|
||||
pow(points.first.x - center.dx, 2) + pow(points.first.y - center.dy, 2),
|
||||
);
|
||||
return CenterAndSize(
|
||||
center: center,
|
||||
size: size * 1.2,
|
||||
);
|
||||
|
||||
}
|
||||
@@ -43,6 +43,7 @@ dependencies:
|
||||
zbar_scan_plugin:
|
||||
git:
|
||||
url: https://github.com/debuggerx01/zbar_scan_plugin.git
|
||||
collection: ^1.17.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
@@ -54,6 +55,7 @@ dev_dependencies:
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^2.0.0
|
||||
yaml: any
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
void main() async {
|
||||
var document = loadYaml(File('pubspec.yaml').readAsStringSync());
|
||||
print(document['version'].replaceAll('+', '.'));
|
||||
}
|
||||
Reference in New Issue
Block a user