vor Import/Export
This commit is contained in:
+38
-69
@@ -211,7 +211,7 @@ function issue_tokens(PDO $pdo, int $uid): array {
|
||||
// =============================================================================
|
||||
|
||||
function igel_list(PDO $pdo, int $uid): void {
|
||||
$stmt = $pdo->prepare('SELECT id, name, gender, feature, note, created_at, updated_at FROM igel WHERE user_id = ? ORDER BY created_at DESC');
|
||||
$stmt = $pdo->prepare('SELECT id, name, gender, feature, note, rescued_at, location, created_at, updated_at FROM igel WHERE user_id = ? ORDER BY created_at DESC');
|
||||
$stmt->execute([$uid]);
|
||||
json($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
}
|
||||
@@ -222,16 +222,36 @@ function igel_create(PDO $pdo, int $uid): void {
|
||||
$gender = isset($in['gender']) ? (string)$in['gender'] : null;
|
||||
$feature = isset($in['feature']) ? (string)$in['feature'] : null;
|
||||
$note = isset($in['note']) ? (string)$in['note'] : null;
|
||||
$rescuedAt = isset($in['rescued_at']) ? (string)$in['rescued_at'] : null; // "YYYY-MM-DD"
|
||||
$location = isset($in['location']) ? trim((string)$in['location']) : null;
|
||||
|
||||
if ($name === '') { json(['error' => 'Name required'], 422); return; }
|
||||
$stmt = $pdo->prepare('INSERT INTO igel(user_id, name, gender, feature, note) VALUES(?,?,?,?,?)');
|
||||
$stmt->execute([$uid, $name, $gender, $feature, $note]);
|
||||
if ($rescuedAt !== null && $rescuedAt !== '' && strtotime($rescuedAt) === false) {
|
||||
json(['error' => 'Invalid rescued_at (expected YYYY-MM-DD)'], 422); return;
|
||||
}
|
||||
if ($location !== null && strlen($location) > 255) {
|
||||
json(['error' => 'Location too long (max 255)'], 422); return;
|
||||
}
|
||||
$stmt = $pdo->prepare(
|
||||
'INSERT INTO igel(user_id, name, gender, feature, note, rescued_at, location)
|
||||
VALUES(?,?,?,?,?,?,?)'
|
||||
);
|
||||
$stmt->execute([$uid, $name, $gender, $feature, $note, $rescuedAt ?: null, $location ?: null]);
|
||||
$id = (int)$pdo->lastInsertId();
|
||||
json(['id' => $id, 'name' => $name, 'gender' => $gender, 'feature' => $feature, 'note' => $note], 201);
|
||||
|
||||
json([
|
||||
'id' => $id,
|
||||
'name' => $name,
|
||||
'gender' => $gender,
|
||||
'feature' => $feature,
|
||||
'note' => $note,
|
||||
'rescued_at' => $rescuedAt,
|
||||
'location' => $location
|
||||
], 201);
|
||||
}
|
||||
|
||||
function igel_get(PDO $pdo, int $uid, int $id): void {
|
||||
$stmt = $pdo->prepare('SELECT id, name, gender, feature, note, created_at, updated_at FROM igel WHERE id=? AND user_id=?');
|
||||
$stmt = $pdo->prepare('SELECT id, name, gender, feature, note, rescued_at, location, created_at, updated_at FROM igel WHERE id=? AND user_id=?');
|
||||
$stmt->execute([$id, $uid]);
|
||||
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if (!$row) { json(['error' => 'Not found'], 404); return; }
|
||||
@@ -244,10 +264,21 @@ function igel_update(PDO $pdo, int $uid, int $id): void {
|
||||
$gender = isset($in['gender']) ? (string)$in['gender'] : null;
|
||||
$feature = isset($in['feature']) ? (string)$in['feature'] : null;
|
||||
$note = isset($in['note']) ? (string)$in['note'] : null;
|
||||
$rescuedAt = array_key_exists('rescued_at', $in) ? (string)$in['rescued_at'] : null;
|
||||
$location = array_key_exists('location', $in) ? trim((string)$in['location']) : null;
|
||||
|
||||
if ($name === '') { json(['error' => 'Name required'], 422); return; }
|
||||
$stmt = $pdo->prepare('UPDATE igel SET name=?, gender=?, feature=?, note=? WHERE id=? AND user_id=?');
|
||||
$stmt->execute([$name, $gender, $feature, $note, $id, $uid]);
|
||||
if ($rescuedAt !== null && $rescuedAt !== '' && strtotime($rescuedAt) === false) {
|
||||
json(['error' => 'Invalid rescued_at (expected YYYY-MM-DD)'], 422); return;
|
||||
}
|
||||
if ($location !== null && strlen($location) > 255) {
|
||||
json(['error' => 'Location too long (max 255)'], 422); return;
|
||||
}
|
||||
|
||||
$stmt = $pdo->prepare(
|
||||
'UPDATE igel SET name=?, gender=?, feature=?, note=?, rescued_at=?, location=? WHERE id=? AND user_id=?'
|
||||
);
|
||||
$stmt->execute([$name, $gender, $feature, $note, $rescuedAt ?: null, $location ?: null, $id, $uid]);
|
||||
json(['ok' => true]);
|
||||
}
|
||||
|
||||
@@ -625,65 +656,3 @@ function jwt_decode(string $token, string $secret): array {
|
||||
if (isset($payload['exp']) && time() >= (int)$payload['exp']) throw new Exception('exp');
|
||||
return $payload;
|
||||
}
|
||||
|
||||
/*
|
||||
-- SQL Reference (run once)
|
||||
|
||||
CREATE TABLE users (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
email VARCHAR(191) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE refresh_tokens (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
token VARCHAR(255) NOT NULL UNIQUE,
|
||||
expires_at DATETIME NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX (user_id), INDEX (token)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE igel (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
user_id BIGINT UNSIGNED NOT NULL,
|
||||
name VARCHAR(120) NOT NULL,
|
||||
gender VARCHAR(30) NULL,
|
||||
feature VARCHAR(255) NULL,
|
||||
note TEXT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
INDEX (user_id), INDEX (name)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE igel_images (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
igel_id BIGINT UNSIGNED NOT NULL,
|
||||
url VARCHAR(500) NOT NULL,
|
||||
thumb_url VARCHAR(500) NULL,
|
||||
original_name VARCHAR(255) NULL,
|
||||
mime VARCHAR(100) NULL,
|
||||
size_bytes BIGINT UNSIGNED NULL,
|
||||
taken_at DATETIME NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (igel_id) REFERENCES igel(id) ON DELETE CASCADE,
|
||||
INDEX (igel_id),
|
||||
INDEX (taken_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE messwerte (
|
||||
id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
||||
igel_id BIGINT UNSIGNED NOT NULL,
|
||||
datum DATETIME NOT NULL,
|
||||
gewicht INT UNSIGNED NOT NULL,
|
||||
behandlung VARCHAR(255) NULL,
|
||||
bemerkung TEXT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (igel_id) REFERENCES igel(id) ON DELETE CASCADE,
|
||||
INDEX (igel_id), INDEX (datum)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
*/
|
||||
?>
|
||||
|
||||
+3
-1
@@ -3,7 +3,7 @@
|
||||
-- https://www.phpmyadmin.net/
|
||||
--
|
||||
-- Host: localhost:3306
|
||||
-- Generation Time: Oct 23, 2025 at 06:57 PM
|
||||
-- Generation Time: Oct 24, 2025 at 10:36 AM
|
||||
-- Server version: 10.6.22-MariaDB-ubu2204-log
|
||||
-- PHP Version: 8.2.28
|
||||
|
||||
@@ -51,6 +51,8 @@ CREATE TABLE `igel` (
|
||||
`gender` varchar(10) DEFAULT NULL,
|
||||
`note` text DEFAULT NULL,
|
||||
`feature` text DEFAULT NULL,
|
||||
`rescued_at` date DEFAULT NULL,
|
||||
`location` varchar(255) DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` timestamp NULL DEFAULT NULL ON UPDATE current_timestamp()
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// lib/features/igel/data/igel_repository.dart
|
||||
import '../../../shared/api_client.dart';
|
||||
import '../domain/igel.dart';
|
||||
|
||||
@@ -12,24 +13,27 @@ class IgelRepository {
|
||||
}
|
||||
|
||||
Future<Igel> create(String name,
|
||||
{String? note, String? gender, String? feature}) async {
|
||||
{String? note,
|
||||
String? gender,
|
||||
String? feature,
|
||||
DateTime? rescuedAt,
|
||||
String? location}) async {
|
||||
String? fmtDate(DateTime? d) =>
|
||||
d == null ? null : d.toIso8601String().split('T').first;
|
||||
final res = await api.post<dynamic>('/igel', {
|
||||
'name': name,
|
||||
'note': note,
|
||||
'gender': gender,
|
||||
'feature': feature,
|
||||
'rescued_at': fmtDate(rescuedAt),
|
||||
'location': (location?.trim().isEmpty ?? true) ? null : location!.trim(),
|
||||
});
|
||||
return Igel.fromMap(res as Map<String, dynamic>);
|
||||
}
|
||||
|
||||
Future<void> update(int id, String name,
|
||||
{String? note, String? gender, String? feature}) async {
|
||||
await api.put<dynamic>('/igel/$id', {
|
||||
'name': name,
|
||||
'note': note,
|
||||
'gender': gender,
|
||||
'feature': feature,
|
||||
});
|
||||
try {
|
||||
final id = (res['id'] as num).toInt();
|
||||
return await get(id);
|
||||
} catch (_) {
|
||||
return Igel.fromMap((res as Map).cast<String, dynamic>());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> delete(int id) async {
|
||||
@@ -40,4 +44,24 @@ class IgelRepository {
|
||||
final map = await api.get<Map<String, dynamic>>('/igel/$id');
|
||||
return Igel.fromMap(map);
|
||||
}
|
||||
|
||||
/// Update hedgehog data. Backend requires name; other fields optional.
|
||||
Future<void> update(int id, String name,
|
||||
{String? note,
|
||||
String? gender,
|
||||
String? feature,
|
||||
DateTime? rescuedAt,
|
||||
String? location}) async {
|
||||
String? fmtDate(DateTime? d) =>
|
||||
d == null ? null : d.toIso8601String().split('T').first;
|
||||
final body = {
|
||||
'name': name,
|
||||
'note': note,
|
||||
'gender': gender,
|
||||
'feature': feature,
|
||||
'rescued_at': fmtDate(rescuedAt),
|
||||
'location': (location?.trim().isEmpty ?? true) ? null : location!.trim(),
|
||||
};
|
||||
await api.put<dynamic>('/igel/$id', body);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@ class Igel {
|
||||
final String? gender; // 'männlich' | 'weiblich' | 'unbekannt'
|
||||
final String? feature; // Merkmal
|
||||
final String? note; // Information
|
||||
|
||||
// 🆕 NEU:
|
||||
final DateTime? rescuedAt; // YYYY-MM-DD (Datum)
|
||||
final String? location; // Ort / Fundstelle
|
||||
|
||||
final DateTime? createdAt;
|
||||
final DateTime? updatedAt;
|
||||
|
||||
@@ -13,52 +18,67 @@ class Igel {
|
||||
this.gender,
|
||||
this.feature,
|
||||
this.note,
|
||||
this.rescuedAt,
|
||||
this.location,
|
||||
this.createdAt,
|
||||
this.updatedAt,
|
||||
});
|
||||
|
||||
// ---------- Factory fromMap ----------
|
||||
factory Igel.fromMap(Map<String, dynamic> map) => Igel(
|
||||
id: (map['id'] as num).toInt(),
|
||||
name: map['name'] as String,
|
||||
gender: map['gender'] as String?,
|
||||
feature: map['feature'] as String?,
|
||||
note: map['note'] as String?,
|
||||
createdAt: map['created_at'] != null
|
||||
? DateTime.parse(map['created_at'])
|
||||
: null,
|
||||
updatedAt: map['updated_at'] != null
|
||||
? DateTime.parse(map['updated_at'])
|
||||
: null,
|
||||
);
|
||||
static DateTime? _parseDateOrNull(String? s) {
|
||||
if (s == null || s.isEmpty) return null;
|
||||
try {
|
||||
return DateTime.parse(s);
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- toMap (optional für PUT/POST) ----------
|
||||
Map<String, dynamic> toMap() => {
|
||||
'id': id,
|
||||
'name': name,
|
||||
if (gender != null) 'gender': gender,
|
||||
if (feature != null) 'feature': feature,
|
||||
if (note != null) 'note': note,
|
||||
if (createdAt != null) 'created_at': createdAt!.toIso8601String(),
|
||||
if (updatedAt != null) 'updated_at': updatedAt!.toIso8601String(),
|
||||
};
|
||||
factory Igel.fromMap(Map<String, dynamic> m) {
|
||||
return Igel(
|
||||
id: (m['id'] as num).toInt(),
|
||||
name: (m['name'] ?? '') as String,
|
||||
gender: m['gender'] as String?,
|
||||
feature: m['feature'] as String?,
|
||||
note: m['note'] as String?,
|
||||
rescuedAt: _parseDateOrNull(m['rescued_at'] as String?),
|
||||
location: m['location'] as String?,
|
||||
createdAt: _parseDateOrNull(m['created_at'] as String?),
|
||||
updatedAt: _parseDateOrNull(m['updated_at'] as String?),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toMapForCreateUpdate() {
|
||||
String? fmtDate(DateTime? d) =>
|
||||
d == null ? null : d.toIso8601String().split('T').first;
|
||||
|
||||
return {
|
||||
'name': name,
|
||||
'gender': gender,
|
||||
'feature': feature,
|
||||
'note': note,
|
||||
'rescued_at': fmtDate(rescuedAt),
|
||||
'location': location?.trim().isEmpty == true ? null : location,
|
||||
};
|
||||
}
|
||||
|
||||
// ---------- copyWith ----------
|
||||
Igel copyWith({
|
||||
int? id,
|
||||
String? name,
|
||||
String? gender,
|
||||
String? feature,
|
||||
String? note,
|
||||
DateTime? rescuedAt,
|
||||
String? location,
|
||||
DateTime? createdAt,
|
||||
DateTime? updatedAt,
|
||||
}) {
|
||||
return Igel(
|
||||
id: id ?? this.id,
|
||||
id: id,
|
||||
name: name ?? this.name,
|
||||
gender: gender ?? this.gender,
|
||||
feature: feature ?? this.feature,
|
||||
note: note ?? this.note,
|
||||
rescuedAt: rescuedAt ?? this.rescuedAt,
|
||||
location: location ?? this.location,
|
||||
createdAt: createdAt ?? this.createdAt,
|
||||
updatedAt: updatedAt ?? this.updatedAt,
|
||||
);
|
||||
|
||||
@@ -43,6 +43,13 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
final nameC = TextEditingController();
|
||||
final featureC = TextEditingController();
|
||||
final noteC = TextEditingController();
|
||||
|
||||
// NEU: Ort/Fundstelle + Gerettet am
|
||||
final locationC = TextEditingController();
|
||||
DateTime? rescuedAt;
|
||||
DateTime? _initRescuedAt;
|
||||
String? _initLocation;
|
||||
|
||||
String? gender; // 'männlich' | 'weiblich' | 'unbekannt' | null
|
||||
|
||||
// Bilder
|
||||
@@ -70,6 +77,7 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
|
||||
featureC.addListener(_markDirtyBasics);
|
||||
noteC.addListener(_markDirtyBasics);
|
||||
locationC.addListener(_markDirtyBasics); // NEU
|
||||
|
||||
_loadAll();
|
||||
}
|
||||
@@ -79,6 +87,7 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
nameC.dispose();
|
||||
featureC.dispose();
|
||||
noteC.dispose();
|
||||
locationC.dispose(); // NEU
|
||||
mwGewichtC.dispose();
|
||||
mwBehandlungC.dispose();
|
||||
mwBemerkungC.dispose();
|
||||
@@ -91,14 +100,25 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
|
||||
bool get _basicsChanged {
|
||||
if (igel == null) return false;
|
||||
|
||||
final newName = nameC.text.trim();
|
||||
final newFeature =
|
||||
featureC.text.trim().isEmpty ? null : featureC.text.trim();
|
||||
final newNote = noteC.text.trim().isEmpty ? null : noteC.text.trim();
|
||||
final changed = newName != igel!.name ||
|
||||
|
||||
bool changed = newName != igel!.name ||
|
||||
newFeature != igel!.feature ||
|
||||
newNote != igel!.note ||
|
||||
gender != igel!.gender;
|
||||
|
||||
// NEU: rescuedAt & location berücksichtigen
|
||||
String? fmt(DateTime? d) =>
|
||||
d == null ? null : DateFormat('yyyy-MM-dd').format(d);
|
||||
if (fmt(rescuedAt) != fmt(_initRescuedAt)) changed = true;
|
||||
|
||||
final newLoc = locationC.text.trim().isEmpty ? null : locationC.text.trim();
|
||||
if (newLoc != (_initLocation?.trim())) changed = true;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
@@ -116,6 +136,12 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
noteC.text = data.note ?? '';
|
||||
gender = data.gender;
|
||||
|
||||
// NEU: rescuedAt + location aus Domain (falls Backend schon erweitert)
|
||||
rescuedAt = data.rescuedAt;
|
||||
locationC.text = data.location ?? '';
|
||||
_initRescuedAt = data.rescuedAt;
|
||||
_initLocation = data.location;
|
||||
|
||||
// Bilder
|
||||
images = await imagesRepo.list(widget.igelId);
|
||||
if (mounted) await _prefetchImages(context);
|
||||
@@ -158,15 +184,31 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
// NEU: rescuedAt + location mitsenden (Repo wurde entsprechend erweitert)
|
||||
await igelRepo.update(
|
||||
widget.igelId,
|
||||
newName,
|
||||
note: newNote,
|
||||
gender: gender,
|
||||
feature: newFeature,
|
||||
rescuedAt: rescuedAt,
|
||||
location: locationC.text.trim().isEmpty ? null : locationC.text.trim(),
|
||||
);
|
||||
|
||||
igel = igel!.copyWith(
|
||||
name: newName, note: newNote, gender: gender, feature: newFeature);
|
||||
name: newName,
|
||||
note: newNote,
|
||||
gender: gender,
|
||||
feature: newFeature,
|
||||
rescuedAt: rescuedAt,
|
||||
location: locationC.text.trim().isEmpty ? null : locationC.text.trim(),
|
||||
);
|
||||
|
||||
// NEU: Init-Stand für Change-Detection aktualisieren
|
||||
_initRescuedAt = rescuedAt;
|
||||
_initLocation =
|
||||
locationC.text.trim().isEmpty ? null : locationC.text.trim();
|
||||
|
||||
setState(() {});
|
||||
_snack('Gespeichert');
|
||||
} catch (e) {
|
||||
@@ -547,6 +589,50 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
prefixIcon: Icon(Icons.style),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// NEU: Gerettet am (Datum)
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading:
|
||||
const Icon(Icons.calendar_today),
|
||||
title: const Text('Gerettet am'),
|
||||
subtitle: Text(
|
||||
rescuedAt == null
|
||||
? '—'
|
||||
: DateFormat('dd.MM.yyyy')
|
||||
.format(rescuedAt!),
|
||||
),
|
||||
onTap: () async {
|
||||
final now = DateTime.now();
|
||||
final init = rescuedAt ?? now;
|
||||
final picked = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: init,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate:
|
||||
DateTime(now.year + 1, 12, 31),
|
||||
);
|
||||
if (picked != null) {
|
||||
setState(() => rescuedAt = picked);
|
||||
}
|
||||
},
|
||||
onLongPress: () =>
|
||||
setState(() => rescuedAt = null),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// NEU: Ort / Fundstelle
|
||||
TextField(
|
||||
controller: locationC,
|
||||
decoration: const InputDecoration(
|
||||
labelText:
|
||||
'Ort / Fundstelle (optional)',
|
||||
prefixIcon:
|
||||
Icon(Icons.place_outlined),
|
||||
),
|
||||
),
|
||||
|
||||
const SizedBox(height: 12),
|
||||
TextField(
|
||||
controller: noteC,
|
||||
@@ -758,7 +844,7 @@ class _IgelDetailState extends ConsumerState<IgelDetailScreen> {
|
||||
),
|
||||
],
|
||||
)),
|
||||
]),
|
||||
]), // for
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -9,7 +9,7 @@ project(runner LANGUAGES CXX)
|
||||
add_executable(${BINARY_NAME} WIN32
|
||||
"flutter_window.cpp"
|
||||
"main.cpp"
|
||||
"utils.cpp"
|
||||
|
||||
"win32_window.cpp"
|
||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
||||
"Runner.rc"
|
||||
|
||||
Reference in New Issue
Block a user