Skip to content

Commit 35426a1

Browse files
committed
add save image function and fix the UI for desktop
1 parent 4c1777e commit 35426a1

13 files changed

+712
-51
lines changed

android/app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
22
package="com.example.text_to_image_gen">
33

4-
<uses-permission android:name="android.permission.INTERNET"/>
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
56
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
6-
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
7+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
8+
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
9+
710
<application
811
android:label="TexFusion"
912
android:name="${applicationName}"

lib/Pages/home_page.dart

Lines changed: 431 additions & 22 deletions
Large diffs are not rendered by default.

lib/Pages/settings_page.dart

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
import 'dart:io';
2+
3+
import 'package:device_info_plus/device_info_plus.dart';
4+
import 'package:file_picker/file_picker.dart';
5+
import 'package:flutter/foundation.dart';
16
import 'package:flutter/material.dart';
27
import 'package:flutter_bloc/flutter_bloc.dart';
8+
import 'package:permission_handler/permission_handler.dart';
9+
import 'package:text_to_image_gen/bloc/app_directory_cubit.dart';
310

411
import '../bloc/app_mode_cubit.dart';
512
import '../bloc/app_theme_cubit.dart';
@@ -17,14 +24,92 @@ class _SettingsPageState extends State<SettingsPage> {
1724
late AppModeCubit _appModeCubit;
1825
late AppThemeCubit _appThemeCubit;
1926
final List<AppTheme> _themes = appThemes.keys.toList();
27+
late AppDirectoryCubit _appDirectoryCubit;
28+
final FilePicker filePicker = FilePicker.platform;
2029

2130
@override
2231
void initState() {
2332
super.initState();
33+
_appDirectoryCubit = context.read<AppDirectoryCubit>()..loadPath();
2434
_appModeCubit = context.read<AppModeCubit>()..loadMode();
2535
_appThemeCubit = context.read<AppThemeCubit>()..loadTheme();
2636
}
2737

38+
Future<void> _pickDirectory() async {
39+
String? directoryPath;
40+
if (Platform.isAndroid) {
41+
AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
42+
int versionNumber = int.parse(androidInfo.version.release.split('.')[0]);
43+
try {
44+
if (versionNumber < 10) {
45+
if (await Permission.storage.isDenied) {
46+
await Permission.storage.request();
47+
} else if (await Permission.storage.isGranted) {
48+
directoryPath = await filePicker.getDirectoryPath();
49+
if (directoryPath != null) {
50+
_appDirectoryCubit.changePath(directoryPath);
51+
} else {
52+
message();
53+
}
54+
} else {
55+
await Permission.storage.request();
56+
}
57+
} else {
58+
if (await Permission.manageExternalStorage.isDenied) {
59+
await Permission.manageExternalStorage.request();
60+
} else if (await Permission.manageExternalStorage.isGranted) {
61+
directoryPath = await filePicker.getDirectoryPath();
62+
if (directoryPath != null) {
63+
_appDirectoryCubit.changePath(directoryPath);
64+
} else {
65+
message();
66+
}
67+
} else {
68+
await Permission.manageExternalStorage.request();
69+
}
70+
}
71+
} catch (e) {
72+
message();
73+
if (kDebugMode) {
74+
print('Error picking directory in android: $e');
75+
}
76+
}
77+
} else {
78+
try {
79+
directoryPath = await filePicker.getDirectoryPath();
80+
if (directoryPath != null) {
81+
_appDirectoryCubit.changePath(directoryPath);
82+
} else {
83+
message();
84+
}
85+
} catch (e) {
86+
message();
87+
if (kDebugMode) {
88+
print('Error picking directory: $e');
89+
}
90+
}
91+
}
92+
}
93+
94+
void message() {
95+
showDialog(
96+
context: context,
97+
builder: (BuildContext context) {
98+
return AlertDialog(
99+
title: const Text('Error'),
100+
content:
101+
const Text('There is error . Try Again later or restart the app'),
102+
actions: <Widget>[
103+
TextButton(
104+
onPressed: () => Navigator.of(context).pop(),
105+
child: const Text('ok'),
106+
),
107+
],
108+
);
109+
},
110+
);
111+
}
112+
28113
@override
29114
Widget build(BuildContext context) {
30115
return Scaffold(
@@ -37,6 +122,21 @@ class _SettingsPageState extends State<SettingsPage> {
37122
crossAxisAlignment: CrossAxisAlignment.center,
38123
mainAxisAlignment: MainAxisAlignment.center,
39124
children: [
125+
BlocBuilder<AppDirectoryCubit, AppDirectoryState>(
126+
builder: (context, state) {
127+
return Padding(
128+
padding: const EdgeInsets.all(8.0),
129+
child: ListTile(
130+
leading: const Icon(Icons.folder),
131+
title: const Text('Main Directory'),
132+
subtitle: Text(state.path),
133+
trailing: ElevatedButton(
134+
onPressed: _pickDirectory,
135+
child: const Text('Change'),
136+
),
137+
),
138+
);
139+
}),
40140
BlocBuilder<AppModeCubit, AppModeState>(
41141
builder: (context, state) {
42142
return Padding(

lib/bloc/app_directory_cubit.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:flutter_bloc/flutter_bloc.dart';
3+
4+
import '../utils/app_directory.dart';
5+
import '../utils/strings.dart';
6+
7+
part 'app_directory_state.dart';
8+
9+
class AppDirectoryCubit extends Cubit<AppDirectoryState> {
10+
AppDirectoryCubit(String path) : super(AppDirectoryInitial(path)){
11+
loadPath();
12+
}
13+
14+
Future<void> loadPath() async {
15+
final selectedPath = await PathSharedPreferences.getPath();
16+
emit(AppDirectoryUpdated(selectedPath ?? pathHint));
17+
}
18+
19+
Future<void> changePath(String value) async {
20+
await PathSharedPreferences.setPath(value);
21+
emit(AppDirectoryUpdated(value));
22+
}
23+
}

lib/bloc/app_directory_state.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
part of 'app_directory_cubit.dart';
2+
3+
abstract class AppDirectoryState extends Equatable {
4+
final String path;
5+
const AppDirectoryState(this.path);
6+
@override
7+
List<Object> get props => [path];
8+
}
9+
10+
class AppDirectoryInitial extends AppDirectoryState {
11+
const AppDirectoryInitial(super.path);
12+
}
13+
class AppDirectoryUpdated extends AppDirectoryState {
14+
const AppDirectoryUpdated(super.path);
15+
}

lib/main.dart

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import 'dart:ui';
22

33
import 'package:flutter/material.dart';
4+
import 'package:flutter/services.dart';
45
import 'package:flutter_bloc/flutter_bloc.dart';
56
import 'package:sentry_flutter/sentry_flutter.dart';
67
import 'package:text_to_image_gen/utils/strings.dart';
78
import 'package:text_to_image_gen/widgets/app_theme.dart';
89

910
import 'Pages/home_page.dart';
1011
import 'Pages/settings_page.dart';
12+
import 'bloc/app_directory_cubit.dart';
1113
import 'bloc/app_mode_cubit.dart';
1214
import 'bloc/app_theme_cubit.dart';
1315

@@ -33,22 +35,31 @@ class MyApp extends StatelessWidget {
3335
BlocProvider(
3436
create: (_) => AppModeCubit(system)..loadMode(),
3537
),
38+
BlocProvider(
39+
create: (_) => AppDirectoryCubit(pathHint)..loadPath(),
40+
),
3641
],
3742
child: BlocBuilder<AppThemeCubit, AppThemeState>(
3843
builder: (context, appTheme) {
3944
return BlocBuilder<AppModeCubit, AppModeState>(
4045
builder: (context, appMode) {
41-
return MaterialApp(
42-
scrollBehavior: CustomScroll(),
43-
initialRoute: '/',
44-
routes: {
45-
'/': (_) => const HomePage(),
46-
'/Settings': (_) => const SettingsPage(),
46+
return Shortcuts(
47+
shortcuts: <LogicalKeySet, Intent>{
48+
LogicalKeySet(LogicalKeyboardKey.select):
49+
const ActivateIntent(),
4750
},
48-
debugShowCheckedModeBanner: false,
49-
themeMode: getMode(appMode.mode),
50-
theme: appTheme.theme.lightTheme,
51-
darkTheme: appTheme.theme.darkTheme,
51+
child: MaterialApp(
52+
scrollBehavior: CustomScroll(),
53+
initialRoute: '/',
54+
routes: {
55+
'/': (_) => const HomePage(),
56+
'/Settings': (_) => const SettingsPage(),
57+
},
58+
debugShowCheckedModeBanner: false,
59+
themeMode: getMode(appMode.mode),
60+
theme: appTheme.theme.lightTheme,
61+
darkTheme: appTheme.theme.darkTheme,
62+
),
5263
);
5364
},
5465
);

lib/utils/app_directory.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'package:shared_preferences/shared_preferences.dart';
2+
3+
class PathSharedPreferences {
4+
static const String _keyPath = 'path';
5+
6+
static Future<void> setPath(String path) async {
7+
final prefs = await SharedPreferences.getInstance();
8+
await prefs.setString(_keyPath, path);
9+
}
10+
11+
static Future<String?> getPath() async {
12+
final prefs = await SharedPreferences.getInstance();
13+
return prefs.getString(_keyPath);
14+
}
15+
}

lib/utils/strings.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import '../widgets/app_theme.dart';
22

33
final appThemes = {
4-
material : 'Material',
4+
material: 'Material',
55
indigoTheme: 'Indigo Nights',
6-
blueWhaleTheme : 'Blue Whale',
7-
goldSunset : 'Gold Sunset',
8-
dellGenoaGreen : 'Dell Genoe Green',
6+
blueWhaleTheme: 'Blue Whale',
7+
goldSunset: 'Gold Sunset',
8+
dellGenoaGreen: 'Dell Genoe Green',
99
};
1010

1111
const system = 'system';
1212
const light = 'light';
1313
const dark = 'dark';
14+
15+
const pathHint = 'Click to choose folder';
16+
const app = 'TexFusion';

macos/Flutter/GeneratedPluginRegistrant.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import FlutterMacOS
66
import Foundation
77

8+
import device_info_plus
89
import package_info_plus
910
import sentry_flutter
1011
import shared_preferences_foundation
1112
import url_launcher_macos
1213

1314
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
15+
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
1416
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
1517
SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin"))
1618
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))

0 commit comments

Comments
 (0)