Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
sun-jiao committed Jul 13, 2023
0 parents commit 73e9d3f
Show file tree
Hide file tree
Showing 68 changed files with 4,326 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
44 changes: 44 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/

# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/

# Symbolication related
app.*.symbols

# Obfuscation related
app.*.map.json

# Android Studio will place build artifacts here
/android/app/debug
/android/app/profile
/android/app/release
45 changes: 45 additions & 0 deletions .metadata
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.

version:
revision: 796c8ef79279f9c774545b3771238c3098dbefab
channel: stable

project_type: app

# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: android
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: ios
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: linux
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: macos
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: web
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab
- platform: windows
create_revision: 796c8ef79279f9c774545b3771238c3098dbefab
base_revision: 796c8ef79279f9c774545b3771238c3098dbefab

# User provided section

# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# renamer
Rename files.
29 changes: 29 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.

# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml

linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule

# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
12 changes: 12 additions & 0 deletions lib/entity/select_x.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import 'package:cross_file/cross_file.dart';

extension SelectX on XFile {
static final List<String> _selection = [];

bool get selected => _selection.contains(path);

set selected(bool val) =>
val ? _selection.add(path) : _selection.remove(path);

static void clear() => _selection.clear();
}
241 changes: 241 additions & 0 deletions lib/files_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import 'package:cross_file/cross_file.dart';
import 'package:desktop_drop/desktop_drop.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';

import 'entity/select_x.dart';

class FilesPage extends StatefulWidget {
const FilesPage({super.key});

@override
State<FilesPage> createState() => _FilesPageState();
}

class _FilesPageState extends State<FilesPage> {
String dropdownValue = 'Files';

final List<XFile> _list = [];

bool _dragging = false;

String filter = '';

Future<void> addFileFromPicker() async {
FilePickerResult? result =
await FilePicker.platform.pickFiles(allowMultiple: true);

if (result != null) {
setState(() {
final resultFiles =
result.files.where((element) => element.path != null).toList();
_list.addAll(List.generate(
resultFiles.length,
(index) => XFile(
resultFiles[index].path!,
name: resultFiles[index].name,
length: resultFiles[index].size,
bytes: resultFiles[index].bytes,
)));
});
}
}

String getNewName(String name) {
return name;
}

List<XFile> _filteredList() {
return _list.where((element) => element.name.contains(filter)).toList();
}

List<TableRow> _tableRows() {
final filteredList = _filteredList();
return List.generate(
filteredList.length,
(index) => TableRow(
decoration: BoxDecoration(
color: index % 2 == 0 ? Colors.white : Colors.blueGrey.shade50,
),
children: [
TableCell(
child: Checkbox(
value: filteredList[index].selected,
onChanged: (val) {
if (val != null) {
setState(() {
filteredList[index].selected = val;
});
}
}),
),
TableCell(
child: Text(filteredList[index].name),
),
TableCell(
child: Text(getNewName(filteredList[index].name)),
),
TableCell(
child: IconButton(
onPressed: () {
setState(() {
_list.removeWhere((element) =>
element.path == filteredList[index].path);
});
},
icon: const Icon(Icons.clear),
),
),
],
));
}

Widget _table() => Table(
columnWidths: const <int, TableColumnWidth>{
0: IntrinsicColumnWidth(),
1: FlexColumnWidth(),
2: FlexColumnWidth(),
3: IntrinsicColumnWidth(),
},
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
border: TableBorder.all(width: 24, color: Colors.transparent),
children: [
TableRow(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
),
children: [
TableCell(
child: Checkbox(
value: _list.every((element) => element.selected),
onChanged: (_) {
setState(() {
if (_list.every((element) => element.selected)) {
SelectX.clear();
} else {
for (var element in _list) {
element.selected = true;
}
}
});
}),
),
const TableCell(
child: Center(
child: Text('Current Name'),
),
),
const TableCell(
child: Center(
child: Text('New Name'),
),
),
TableCell(
child: IconButton(
onPressed: () {
_list.clear();
},
icon: const Icon(Icons.clear),
),
),
],
),
..._tableRows(),
],
);

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
children: <Widget>[
DropdownButton<String>(
value: dropdownValue,
focusColor: Colors.transparent,
underline: const SizedBox(),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: <String>['Files', 'Folders', 'Files & Folders']
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
),
const Expanded(
child: TextField(
decoration: InputDecoration(
hintText: 'Filter',
),
),
),
],
),
const SizedBox(height: 16),
Expanded(
child: DropTarget(
onDragDone: (detail) {
setState(() {
_list.addAll(detail.files);
});
},
onDragEntered: (detail) {
setState(() {
_dragging = true;
});
},
onDragExited: (detail) {
setState(() {
_dragging = false;
});
},
child: Container(
color: Colors.white,
child: Stack(
children: [
if (_list.isNotEmpty)
_table()
else if (!_dragging)
const Center(
child: Text('Drag and drop to add files.'),
),
if (_dragging)
Container(
color: Colors.blue.withOpacity(0.2),
child: const Center(
child: Text('Drop to add files.'),
),
)
],
),
),
),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
ElevatedButton(
onPressed: () {},
child: const Text('Rename'),
),
const SizedBox(width: 16),
ElevatedButton(
onPressed: addFileFromPicker,
child: const Text('Add File'),
),
],
),
],
),
);
}
}
Loading

0 comments on commit 73e9d3f

Please sign in to comment.