release 4.8.9

This commit is contained in:
2024-08-05 03:08:12 +09:00
parent 1e0af0b06b
commit 66ade1fe09
30 changed files with 1765 additions and 17646 deletions

View File

@ -1,9 +1,12 @@
import 'dart:async';
import 'dart:convert'; // この行を追加または確認
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:path_provider/path_provider.dart';
import 'package:rogapp/model/destination.dart';
import 'package:rogapp/pages/destination/destination_controller.dart';
import 'package:rogapp/pages/index/index_controller.dart';
@ -493,7 +496,10 @@ class CameraPage extends StatelessWidget {
if (buyPointPhoto == true) {
// buyPointPhotoがtrueの場合は、BuyPointCameraウィジェットを返します。
//print("--- buy point camera ${destination.toString()}");
return BuyPointCamera(destination: destination);
//return BuyPointCamera(destination: destination);
return SwitchableBuyPointCamera(destination: destination);
//}else if(destination.use_qr_code){
// return QRCodeScannerPage(destination: destination);
} else if (destinationController.isInRog.value) {
@ -617,105 +623,189 @@ class StartRogaining extends StatelessWidget {
// 完了ボタンをタップすると、購入ポイントの処理が行われます。
// 購入なしボタンをタップすると、購入ポイントがキャンセルされます。
//
class SwitchableBuyPointCamera extends StatefulWidget {
final Destination destination;
const SwitchableBuyPointCamera({Key? key, required this.destination}) : super(key: key);
@override
_SwitchableBuyPointCameraState createState() => _SwitchableBuyPointCameraState();
}
class _SwitchableBuyPointCameraState extends State<SwitchableBuyPointCamera> {
bool isQRMode = true;
@override
Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width;
final screenHeight = MediaQuery.of(context).size.height;
final qrViewWidth = screenWidth * 2 / 3;
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text("${widget.destination.sub_loc_id} : ${widget.destination.name}"),
),
body: SafeArea(
child: Stack(
children: [
if (isQRMode)
Column(
children: [
SizedBox(height: screenHeight * 0.1),
Center(
child: SizedBox(
width: qrViewWidth,
height: qrViewWidth,
child: BuyPointCamera_QR(destination: widget.destination),
),
),
Expanded(
child: Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Text(
"岐阜ロゲQRコードにかざしてください。",
style: TextStyle(fontSize: 16),
),
),
),
),
],
)
else
Positioned.fill(
child: BuyPointCamera(destination: widget.destination),
),
Positioned(
right: 16,
bottom: 16,
child: Container(
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.7),
borderRadius: BorderRadius.circular(20),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(isQRMode ? "カメラへ" : "QRへ"),
Switch(
value: isQRMode,
onChanged: (value) {
setState(() {
isQRMode = value;
});
},
),
],
),
),
),
],
),
),
);
}
}
class BuyPointCamera extends StatelessWidget {
BuyPointCamera({Key? key, required this.destination}) : super(key: key);
Destination destination;
DestinationController destinationController =
Get.find<DestinationController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text(
"${destination.sub_loc_id} : ${destination.name}",
),
),
body: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Obx(
() => Container(
width: MediaQuery.of(context).size.width,
height: 370,
decoration: BoxDecoration(
image: DecorationImage(
// 要修正getReceiptImage関数の戻り値がnullの場合のエラーハンドリングが不十分です。適切なデフォルト画像を表示するなどの処理を追加してください。
//
image: getReceiptImage(), fit: BoxFit.cover)),
),
),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(getTagText(true, destination.tags)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Wrap(
spacing: 16.0,
runSpacing: 8.0,
children: [
Obx(() => ElevatedButton(
onPressed: () {
destinationController.openCamera(context, destination);
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(20),
backgroundColor: destinationController.photos.isEmpty
? Colors.red
: Colors.grey[300],
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Obx(
() =>
Container(
width: MediaQuery
.of(context)
.size
.width,
height: 370,
decoration: BoxDecoration(
image: DecorationImage(
// 要修正getReceiptImage関数の戻り値がnullの場合のエラーハンドリングが不十分です。適切なデフォルト画像を表示するなどの処理を追加してください。
//
image: getReceiptImage(), fit: BoxFit.cover)),
),
child: destinationController.photos.isEmpty
? const Text("撮影",
style: TextStyle(color: Colors.white))
: const Text("再撮影",
style: TextStyle(color: Colors.black)),
)),
ElevatedButton(
onPressed: () async {
await destinationController.cancelBuyPoint(destination);
Navigator.of(Get.context!).pop();
destinationController.rogainingCounted.value = true;
destinationController.skipGps = false;
destinationController.isPhotoShoot.value = false;
},
child: const Text("買い物なし")),
Obx(() => destinationController.photos.isNotEmpty
? ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red),
onPressed: () async {
await destinationController.makeBuyPoint(
destination,
destinationController.photos[0].path);
Get.back();
destinationController.rogainingCounted.value = true;
destinationController.skipGps = false;
destinationController.isPhotoShoot.value = false;
Get.snackbar("お買い物加点を行いました",
"${destination.sub_loc_id} : ${destination.name}",
backgroundColor: Colors.green,
colorText: Colors.white);
},
child: const Text("完了",
style: TextStyle(color: Colors.white)))
: Container())
],
),
),
],
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(getTagText(true, destination.tags)),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16.0),
child: Wrap(
spacing: 16.0,
runSpacing: 8.0,
children: [
Obx(() =>
ElevatedButton(
onPressed: () {
destinationController.openCamera(context, destination);
},
style: ElevatedButton.styleFrom(
shape: const CircleBorder(),
padding: const EdgeInsets.all(20),
backgroundColor: destinationController.photos.isEmpty
? Colors.red
: Colors.grey[300],
),
child: destinationController.photos.isEmpty
? const Text("撮影",
style: TextStyle(color: Colors.white))
: const Text("再撮影",
style: TextStyle(color: Colors.black)),
)),
ElevatedButton(
onPressed: () async {
await destinationController.cancelBuyPoint(destination);
Navigator.of(Get.context!).pop();
destinationController.rogainingCounted.value = true;
destinationController.skipGps = false;
destinationController.isPhotoShoot.value = false;
},
child: const Text("買い物なし")),
Obx(() =>
destinationController.photos.isNotEmpty
? ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red),
onPressed: () async {
await destinationController.makeBuyPoint(
destination,
destinationController.photos[0].path);
Get.back();
destinationController.rogainingCounted.value = true;
destinationController.skipGps = false;
destinationController.isPhotoShoot.value = false;
Get.snackbar("お買い物加点を行いました",
"${destination.sub_loc_id} : ${destination.name}",
backgroundColor: Colors.green,
colorText: Colors.white);
},
child: const Text("完了",
style: TextStyle(color: Colors.white)))
: Container())
],
),
),
],
),
);
}
@ -743,28 +833,9 @@ class _BuyPointCamera_QRState extends State<BuyPointCamera_QR> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: Text("${widget.destination.sub_loc_id} : ${widget.destination.name}"),
),
body: Column(
children: [
Expanded(
flex: 4,
child: QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
),
),
Expanded(
flex: 1,
child: Center(
child: Text('QRコードをスキャンしてください'),
),
),
],
),
return QRView(
key: qrKey,
onQRViewCreated: _onQRViewCreated,
);
}
@ -773,11 +844,39 @@ class _BuyPointCamera_QRState extends State<BuyPointCamera_QR> {
controller.scannedDataStream.listen((scanData) {
if (!isQRScanned && scanData.code != null && scanData.code!.startsWith('https://rogaining.sumasen.net/api/activate_buy_point/')) {
isQRScanned = true;
_activateBuyPoint(scanData.code!);
_processBuyPoint();
//_activateBuyPoint(scanData.code!);
}
});
}
Future<String> getImageFilePathFromAssets(String assetPath) async {
final byteData = await rootBundle.load(assetPath);
final buffer = byteData.buffer;
Directory tempDir = await getTemporaryDirectory();
String tempPath = tempDir.path;
var filePath = '$tempPath/temp_qr_receipt.png';
return (await File(filePath).writeAsBytes(
buffer.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes)
)).path;
}
void _processBuyPoint() async {
// アセットの画像をテンポラリファイルにコピー
String predefinedImagePath = await getImageFilePathFromAssets('assets/images/QR_certificate.png');
try {
await destinationController.makeBuyPoint(widget.destination, predefinedImagePath);
Get.snackbar('成功', 'お買い物ポイントが有効化されました');
Navigator.of(context).pop();
} catch (e) {
Get.snackbar('エラー', 'お買い物ポイントの有効化に失敗しました');
} finally {
isQRScanned = false;
}
}
void _activateBuyPoint(String qrCode) async {
final IndexController indexController = Get.find<IndexController>();