Skip to content

Commit 51f7d97

Browse files
committed
Community rights
1 parent 516e885 commit 51f7d97

14 files changed

Lines changed: 165 additions & 45 deletions

lib/api/albums.dart

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:piwigo_ng/models/album_model.dart';
77
import 'package:piwigo_ng/services/preferences_service.dart';
88

99
import 'api_client.dart';
10+
import 'authentication.dart';
1011

1112
Future<ApiResult<List<AlbumModel>>> fetchAlbums(int albumID) async {
1213
final Map<String, dynamic> queries = {
@@ -16,6 +17,57 @@ Future<ApiResult<List<AlbumModel>>> fetchAlbums(int albumID) async {
1617
'thumbnail_size': Preferences.getAlbumThumbnailSize,
1718
};
1819

20+
try {
21+
List<String> uploadCategoryIdList = [];
22+
if (await methodExist('community.categories.getList')) {
23+
queries['faked_by_community'] = false;
24+
ApiResult communityResult = await fetchCommunityAlbums(albumID);
25+
if (communityResult.hasData) {
26+
uploadCategoryIdList = communityResult.data.map<String>(
27+
(cat) {
28+
return cat.id.toString();
29+
},
30+
).toList();
31+
}
32+
}
33+
34+
Response response = await ApiClient.get(
35+
queryParameters: queries,
36+
);
37+
38+
if (response.statusCode == 200) {
39+
List<dynamic> jsonAlbums = json.decode(response.data)['result']['categories'];
40+
List<AlbumModel> albums = List<AlbumModel>.from(jsonAlbums.map(
41+
(album) {
42+
print(album);
43+
bool canUpload = false;
44+
if ((appPreferences.getBool(Preferences.isAdminKey) ?? false) ||
45+
uploadCategoryIdList.contains(album['id'].toString())) {
46+
canUpload = true;
47+
}
48+
album['can_upload'] = canUpload;
49+
return AlbumModel.fromJson(album);
50+
},
51+
));
52+
return ApiResult<List<AlbumModel>>(
53+
data: albums,
54+
);
55+
}
56+
} on DioError catch (e) {
57+
debugPrint(e.message);
58+
} catch (e) {
59+
debugPrint("$e");
60+
}
61+
return ApiResult(error: ApiErrors.fetchAlbumsError);
62+
}
63+
64+
Future<ApiResult<List<AlbumModel>>> fetchCommunityAlbums(int albumID) async {
65+
final Map<String, dynamic> queries = {
66+
'format': 'json',
67+
'method': 'community.categories.getList',
68+
'cat_id': albumID,
69+
};
70+
1971
try {
2072
Response response = await ApiClient.get(
2173
queryParameters: queries,

lib/api/authentication.dart

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,40 @@ import 'package:piwigo_ng/services/preferences_service.dart';
1010

1111
import 'api_client.dart';
1212

13+
Future<ApiResult<String>> pingAPI() async {
14+
Map<String, String> queries = {
15+
'format': 'json',
16+
'method': 'pwg.getVersion',
17+
};
18+
19+
try {
20+
Response response = await ApiClient.get(queryParameters: queries);
21+
var data = json.decode(response.data);
22+
if (data['stat'] == 'ok') {
23+
return ApiResult<String>(data: data['result']);
24+
}
25+
} on DioError catch (e) {
26+
debugPrint(e.message);
27+
} catch (e) {
28+
debugPrint('Error $e');
29+
}
30+
return ApiResult(error: ApiErrors.error);
31+
}
32+
1333
Future<ApiResult<bool>> loginUser(
1434
String url, {
1535
String username = '',
1636
String password = '',
1737
}) async {
18-
if (url.isEmpty) {}
38+
if (url.isEmpty) {
39+
return ApiResult<bool>(
40+
data: false,
41+
error: ApiErrors.wrongServerUrl,
42+
);
43+
}
44+
1945
FlutterSecureStorage secureStorage = const FlutterSecureStorage();
2046
await secureStorage.write(key: 'SERVER_URL', value: url);
21-
print(url);
2247

2348
if (username.isEmpty && password.isEmpty) {
2449
ApiResult<StatusModel> status = await sessionStatus();
@@ -83,6 +108,10 @@ Future<ApiResult<StatusModel>> sessionStatus() async {
83108
Response response = await ApiClient.get(queryParameters: queries);
84109
var data = json.decode(response.data);
85110
if (data['stat'] == 'ok') {
111+
if (await methodExist('community.session.getStatus')) {
112+
String? community = await communityStatus();
113+
data['result']['real_user_status'] = community;
114+
}
86115
return ApiResult<StatusModel>(
87116
data: StatusModel.fromJson(data['result']),
88117
);
@@ -97,6 +126,23 @@ Future<ApiResult<StatusModel>> sessionStatus() async {
97126
);
98127
}
99128

129+
Future<String?> communityStatus() async {
130+
Map<String, String> queries = {'format': 'json', 'method': 'community.session.getStatus'};
131+
132+
try {
133+
Response response = await ApiClient.get(queryParameters: queries);
134+
var data = json.decode(response.data);
135+
if (data['stat'] == 'ok') {
136+
return data['result']['real_user_status'];
137+
}
138+
} on DioError catch (e) {
139+
debugPrint(e.message);
140+
} catch (e) {
141+
debugPrint('Error $e');
142+
}
143+
return null;
144+
}
145+
100146
Future<ApiResult<InfoModel>> getInfo() async {
101147
Map<String, String> queries = {'format': 'json', 'method': 'pwg.getInfos'};
102148

lib/api/upload.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Future<File?> compressFile(XFile file) async {
141141
final filePath = file.path;
142142
var dir = await getTemporaryDirectory();
143143
String filename = filePath.split('/').last;
144-
final outPath = "${dir.path}/compressed_$filename";
144+
final outPath = "${dir.path}/compressed/$filename";
145145

146146
var result = await FlutterImageCompress.compressAndGetFile(
147147
filePath,

lib/components/appbars/root_search_app_bar.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ class _RootSearchAppBarState extends State<RootSearchAppBar> {
8686
),
8787
),
8888
actions: [
89-
IconButton(
90-
onPressed: () {},
91-
icon: const Icon(Icons.more_vert),
92-
),
89+
SizedBox(width: 16.0),
90+
// IconButton(
91+
// onPressed: () {},
92+
// icon: const Icon(Icons.more_vert),
93+
// ),
9394
],
9495
expandedHeight: _expandedHeight,
9596
flexibleSpace: FlexibleSpaceBar(

lib/components/buttons/animated_piwigo_button.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@ class AnimatedPiwigoButton extends StatelessWidget {
2727
child: LayoutBuilder(builder: (context, constraints) {
2828
return RoundedLoadingButton(
2929
controller: controller,
30-
duration: const Duration(milliseconds: 300),
30+
duration: const Duration(milliseconds: 500),
3131
completionDuration: const Duration(milliseconds: 300),
32-
resetDuration: const Duration(seconds: 1),
33-
resetAfterDuration: true,
32+
// resetDuration: const Duration(seconds: 1),
33+
resetAfterDuration: false,
3434
animateOnTap: false,
3535
color: color,
3636
elevation: 0.0,

lib/components/modals/add_tags_modal.dart

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ class _AddTagsModalState extends State<AddTagsModal> {
5353
TagModel? addedTag = await showCreateTagModal(context);
5454
if (addedTag == null) return;
5555
await _onRefresh();
56-
setState(() {
57-
_selectedTagList.add(_tagList.firstWhere((tag) => tag.id == addedTag.id));
58-
});
56+
try {
57+
setState(() {
58+
_selectedTagList.add(_tagList.where((tag) => tag.id == addedTag.id).first);
59+
});
60+
} on StateError catch (e) {
61+
debugPrint('Can\'t fetch new tag');
62+
}
5963
}
6064

6165
void _onSelectTag(TagModel tag) {

lib/components/scroll_widgets/album_grid_view.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class AlbumGridView extends StatelessWidget {
1515
this.onDelete,
1616
this.onEdit,
1717
this.onMove,
18+
this.isAdmin = false,
1819
}) : super(key: key);
1920

2021
final List<AlbumModel> albumList;
@@ -23,6 +24,7 @@ class AlbumGridView extends StatelessWidget {
2324
final Function(AlbumModel)? onEdit;
2425
final Function(AlbumModel)? onMove;
2526
final EdgeInsetsGeometry? padding;
27+
final bool isAdmin;
2628

2729
@override
2830
Widget build(BuildContext context) {
@@ -40,6 +42,7 @@ class AlbumGridView extends StatelessWidget {
4042
itemBuilder: (context, index) {
4143
AlbumModel album = albumList[index];
4244
return AlbumCard(
45+
showActions: isAdmin,
4346
album: album,
4447
onTap: () => onTap?.call(album),
4548
onDelete: () => onDelete?.call(album),

lib/models/album_model.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class AlbumModel {
1717
String? dateLast;
1818
String? dateLastMax;
1919
List<AlbumModel> children;
20+
bool canUpload;
2021

2122
AlbumModel({
2223
required this.id,
@@ -36,6 +37,7 @@ class AlbumModel {
3637
this.idRepresentative,
3738
this.dateLast,
3839
this.dateLastMax,
40+
this.canUpload = true,
3941
List<AlbumModel>? children,
4042
}) : children = children ?? [],
4143
fullName = fullName ?? name;
@@ -58,5 +60,6 @@ class AlbumModel {
5860
children = json['sub_categories']?.map<AlbumModel>((a) => AlbumModel.fromJson(a)).toList() ?? [],
5961
idRepresentative = json['representative_picture_id'],
6062
dateLast = json['date_last'],
61-
dateLastMax = json['max_date_last'];
63+
dateLastMax = json['max_date_last'],
64+
canUpload = json['can_upload'] ?? true;
6265
}

lib/models/status_model.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class StatusModel {
22
String username;
33
String status;
4+
String? realStatus;
45
String? theme;
56
String language;
67
String pwgToken;
@@ -14,6 +15,7 @@ class StatusModel {
1415
StatusModel.fromJson(Map<String, dynamic> json)
1516
: username = json['username'] ?? 'guest',
1617
status = json['status'] ?? 'guest',
18+
realStatus = json['real_user_status'],
1719
theme = json['theme'],
1820
language = json['language'] ?? 'en_US',
1921
pwgToken = json['pwg_token'] ?? '',

lib/services/preferences_service.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Preferences {
1919

2020
static const String accountUsernameKey = 'ACCOUNT_USERNAME';
2121
static const String userStatusKey = 'USER_STATUS';
22+
static const String communityStatusKey = 'COMMUNITY_STATUS';
2223
static const String tokenKey = 'PWG_TOKEN';
2324
static const String versionKey = 'VERSION';
2425
static const String availableSizesKey = 'AVAILABLE_SIZES';
@@ -125,7 +126,11 @@ class Preferences {
125126
appPreferences.setString(tokenKey, status.pwgToken);
126127
appPreferences.setString(versionKey, status.version);
127128
appPreferences.setStringList(availableSizesKey, status.availableSizes);
128-
if (["admin", "webmaster"].contains(status.status)) {
129+
if (status.realStatus != null) {
130+
appPreferences.setString(communityStatusKey, status.status);
131+
status.status = status.realStatus!;
132+
}
133+
if (['admin', 'webmaster'].contains(status.status)) {
129134
appPreferences.setBool(isAdminKey, true);
130135
appPreferences.setInt(uploadChunkSizeKey, status.uploadFormChunkSize ?? 0);
131136
appPreferences.setString(fileTypesKey, status.uploadFileTypes ?? '');

0 commit comments

Comments
 (0)