kopia lustrzana https://gitlab.com/mysocialportal/relatica
Add visibility lookup to editor and fix private Circles selector overflow
rodzic
8b99f73238
commit
479fa2a545
|
@ -14,6 +14,7 @@ import '../../utils/active_profile_selector.dart';
|
|||
import '../../utils/dateutils.dart';
|
||||
import '../image_control.dart';
|
||||
import '../padding.dart';
|
||||
import '../visibility_dialog.dart';
|
||||
|
||||
class StatusHeaderControl extends StatelessWidget {
|
||||
static final _logger = Logger('$StatusHeaderControl');
|
||||
|
@ -124,7 +125,7 @@ class StatusHeaderControl extends StatelessWidget {
|
|||
),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await _showVisibilityDialog(context, manager, entry.visibility);
|
||||
await showVisibilityDialog(context, manager, entry.visibility);
|
||||
},
|
||||
icon: Icon(
|
||||
entry.visibility.type == v.VisibilityType.public
|
||||
|
@ -140,141 +141,3 @@ class StatusHeaderControl extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool?> _showVisibilityDialog(
|
||||
BuildContext context,
|
||||
ConnectionsManager cm,
|
||||
v.Visibility visibility,
|
||||
) async {
|
||||
final circlesMap = {for (var item in cm.getMyCircles()) item.id: item};
|
||||
|
||||
final allowedCircles = visibility.allowedCircleIds.map((c) {
|
||||
if (c == '~') {
|
||||
return 'Followers';
|
||||
}
|
||||
|
||||
return circlesMap[c]?.name ?? 'Circle #$c';
|
||||
});
|
||||
|
||||
final excludedCircles = visibility.excludedCircleIds.map((c) {
|
||||
if (c == '~') {
|
||||
return 'Followers';
|
||||
}
|
||||
|
||||
return circlesMap[c]?.name ?? 'Circle #$c';
|
||||
});
|
||||
|
||||
final allowedUsers = visibility.allowedUserIds.map(
|
||||
(u) => cm.getById(u).fold(
|
||||
onSuccess: (connection) => connection.handle,
|
||||
onError: (_) => 'User $u',
|
||||
),
|
||||
);
|
||||
|
||||
final excludedUsers = visibility.excludedUserIds.map(
|
||||
(u) => cm.getById(u).fold(
|
||||
onSuccess: (connection) => connection.handle,
|
||||
onError: (_) => 'User $u',
|
||||
),
|
||||
);
|
||||
|
||||
return showDialog<bool>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Visibility Details',
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge
|
||||
?.copyWith(decoration: TextDecoration.underline),
|
||||
),
|
||||
if (visibility.type == v.VisibilityType.public) ...[
|
||||
const Text('Public')
|
||||
],
|
||||
if (visibility.type != v.VisibilityType.public) ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Allowed Users: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
allowedUsers.isEmpty
|
||||
? 'Empty'
|
||||
: allowedUsers.join(', '),
|
||||
softWrap: true,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Allowed Circles: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
allowedCircles.isEmpty
|
||||
? 'Empty'
|
||||
: allowedCircles.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Excluded Users: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
excludedUsers.isEmpty ? 'Empty' : excludedUsers.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Excluded Circles: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
excludedCircles.isEmpty
|
||||
? 'Empty'
|
||||
: excludedCircles.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
ElevatedButton(
|
||||
child: const Text('Dismiss'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, true); // showDialog() returns true
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../models/visibility.dart' as v;
|
||||
import '../services/connections_manager.dart';
|
||||
|
||||
Future<bool?> showVisibilityDialog(
|
||||
BuildContext context,
|
||||
ConnectionsManager cm,
|
||||
v.Visibility visibility,
|
||||
) async {
|
||||
final circlesMap = {for (var item in cm.getMyCircles()) item.id: item};
|
||||
|
||||
final allowedCircles = visibility.allowedCircleIds.map((c) {
|
||||
if (c == '~') {
|
||||
return 'Followers';
|
||||
}
|
||||
|
||||
return circlesMap[c]?.name ?? 'Circle #$c';
|
||||
});
|
||||
|
||||
final excludedCircles = visibility.excludedCircleIds.map((c) {
|
||||
if (c == '~') {
|
||||
return 'Followers';
|
||||
}
|
||||
|
||||
return circlesMap[c]?.name ?? 'Circle #$c';
|
||||
});
|
||||
|
||||
final allowedUsers = visibility.allowedUserIds.map(
|
||||
(u) => cm.getById(u).fold(
|
||||
onSuccess: (connection) => connection.handle,
|
||||
onError: (_) => 'User $u',
|
||||
),
|
||||
);
|
||||
|
||||
final excludedUsers = visibility.excludedUserIds.map(
|
||||
(u) => cm.getById(u).fold(
|
||||
onSuccess: (connection) => connection.handle,
|
||||
onError: (_) => 'User $u',
|
||||
),
|
||||
);
|
||||
|
||||
return showDialog<bool>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'Visibility Details',
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.bodyLarge
|
||||
?.copyWith(decoration: TextDecoration.underline),
|
||||
),
|
||||
if (visibility.type == v.VisibilityType.public) ...[
|
||||
const Text('Public')
|
||||
],
|
||||
if (visibility.type != v.VisibilityType.public) ...[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Allowed Users: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
allowedUsers.isEmpty
|
||||
? 'Empty'
|
||||
: allowedUsers.join(', '),
|
||||
softWrap: true,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Allowed Circles: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
allowedCircles.isEmpty
|
||||
? 'Empty'
|
||||
: allowedCircles.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Excluded Users: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
excludedUsers.isEmpty ? 'Empty' : excludedUsers.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
const Text(
|
||||
'Excluded Circles: ',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
excludedCircles.isEmpty
|
||||
? 'Empty'
|
||||
: excludedCircles.join(','),
|
||||
softWrap: true,
|
||||
)
|
||||
],
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
ElevatedButton(
|
||||
child: const Text('Dismiss'),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, true); // showDialog() returns true
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
|
@ -15,6 +15,7 @@ import '../controls/login_aware_cached_network_image.dart';
|
|||
import '../controls/padding.dart';
|
||||
import '../controls/standard_appbar.dart';
|
||||
import '../controls/timeline/status_header_control.dart';
|
||||
import '../controls/visibility_dialog.dart';
|
||||
import '../globals.dart';
|
||||
import '../models/circle_data.dart';
|
||||
import '../models/exec_error.dart';
|
||||
|
@ -24,6 +25,7 @@ import '../models/media_attachment_uploads/new_entry_media_items.dart';
|
|||
import '../models/timeline_entry.dart';
|
||||
import '../models/visibility.dart';
|
||||
import '../serializers/friendica/link_preview_friendica_extensions.dart';
|
||||
import '../services/connections_manager.dart';
|
||||
import '../services/feature_version_checker.dart';
|
||||
import '../services/timeline_manager.dart';
|
||||
import '../utils/active_profile_selector.dart';
|
||||
|
@ -566,13 +568,22 @@ class _EditorScreenState extends State<EditorScreen> {
|
|||
|
||||
Widget buildVisibilitySelector(BuildContext context) {
|
||||
if (widget.forEditing || widget.parentId.isNotEmpty) {
|
||||
final cm = context
|
||||
.read<ActiveProfileSelector<ConnectionsManager>>()
|
||||
.activeEntry
|
||||
.value;
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
const Text('Visibility:'),
|
||||
const HorizontalPadding(),
|
||||
visibility.type == VisibilityType.public
|
||||
? const Icon(Icons.public)
|
||||
: const Icon(Icons.lock),
|
||||
IconButton(
|
||||
onPressed: () async {
|
||||
await showVisibilityDialog(context, cm, visibility);
|
||||
},
|
||||
icon: visibility.type == VisibilityType.public
|
||||
? const Icon(Icons.public)
|
||||
: const Icon(Icons.lock),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
@ -583,67 +594,74 @@ class _EditorScreenState extends State<EditorScreen> {
|
|||
.getValueOrElse(() => []);
|
||||
circles.sort((g1, g2) => g1.name.compareTo(g2.name));
|
||||
|
||||
final circleMenuItems = <DropdownMenuEntry<CircleData>>[];
|
||||
circleMenuItems.add(DropdownMenuEntry(
|
||||
final circleMenuItems = <DropdownMenuItem<CircleData>>[];
|
||||
circleMenuItems.add(DropdownMenuItem(
|
||||
value: CircleData.followersPseudoCircle,
|
||||
label: CircleData.followersPseudoCircle.name));
|
||||
circleMenuItems.add(DropdownMenuEntry(
|
||||
value: CircleData('', ''), label: '-', enabled: false));
|
||||
circleMenuItems.addAll(circles.map((g) => DropdownMenuEntry(
|
||||
child: Text(CircleData.followersPseudoCircle.name)));
|
||||
circleMenuItems.add(DropdownMenuItem(
|
||||
value: CircleData('', ''), child: const Divider(), enabled: false));
|
||||
circleMenuItems.addAll(circles.map((g) => DropdownMenuItem(
|
||||
value: g,
|
||||
label: g.name,
|
||||
child: Text(g.name),
|
||||
)));
|
||||
if (!circles.contains(currentCircle)) {
|
||||
if (currentCircle != CircleData.followersPseudoCircle &&
|
||||
!circles.contains(currentCircle)) {
|
||||
currentCircle = null;
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
const Text('Visibility:'),
|
||||
const HorizontalPadding(),
|
||||
DropdownMenu<VisibilityType>(
|
||||
initialSelection: visibility.type,
|
||||
enabled: !widget.forEditing,
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
if (value == VisibilityType.public) {
|
||||
visibility = Visibility.public();
|
||||
return;
|
||||
}
|
||||
DropdownButton<VisibilityType>(
|
||||
value: visibility.type,
|
||||
onChanged: widget.forEditing
|
||||
? null
|
||||
: (value) {
|
||||
setState(() {
|
||||
if (value == VisibilityType.public) {
|
||||
visibility = Visibility.public();
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == VisibilityType.private && currentCircle == null) {
|
||||
visibility = Visibility.private();
|
||||
return;
|
||||
}
|
||||
if (value == VisibilityType.private &&
|
||||
currentCircle == null) {
|
||||
visibility = Visibility.private();
|
||||
return;
|
||||
}
|
||||
|
||||
visibility = Visibility(
|
||||
type: VisibilityType.private,
|
||||
allowedCircleIds: [currentCircle!.id],
|
||||
);
|
||||
});
|
||||
},
|
||||
dropdownMenuEntries: VisibilityType.values
|
||||
.map((v) => DropdownMenuEntry(
|
||||
visibility = Visibility(
|
||||
type: VisibilityType.private,
|
||||
allowedCircleIds: [currentCircle!.id],
|
||||
);
|
||||
});
|
||||
},
|
||||
items: VisibilityType.values
|
||||
.map((v) => DropdownMenuItem(
|
||||
value: v,
|
||||
label: v.toLabel(),
|
||||
child: Text(v.toLabel()),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
const HorizontalPadding(),
|
||||
if (visibility.type == VisibilityType.private)
|
||||
DropdownMenu<CircleData>(
|
||||
enabled: !widget.forEditing,
|
||||
initialSelection: currentCircle,
|
||||
onSelected: (value) {
|
||||
setState(() {
|
||||
currentCircle = value;
|
||||
visibility = Visibility(
|
||||
type: VisibilityType.private,
|
||||
allowedCircleIds:
|
||||
currentCircle == null ? [] : [currentCircle!.id],
|
||||
);
|
||||
});
|
||||
},
|
||||
dropdownMenuEntries: circleMenuItems,
|
||||
Expanded(
|
||||
child: DropdownButton<CircleData>(
|
||||
value: currentCircle,
|
||||
isExpanded: true,
|
||||
onChanged: widget.forEditing
|
||||
? null
|
||||
: (value) {
|
||||
setState(() {
|
||||
currentCircle = value;
|
||||
visibility = Visibility(
|
||||
type: VisibilityType.private,
|
||||
allowedCircleIds:
|
||||
currentCircle == null ? [] : [currentCircle!.id],
|
||||
);
|
||||
});
|
||||
},
|
||||
items: circleMenuItems,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue