Added ExpandableText and made some adjustments.
parent
9a7a8f9f39
commit
c0f971c0d3
|
@ -32,28 +32,28 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
ElevatedButton.icon(
|
||||||
|
icon: const Icon(Icons.my_location),
|
||||||
|
onPressed: _getCurrentLocation,
|
||||||
|
label: const Text('Current Position'),
|
||||||
|
),
|
||||||
|
const SizedBox(height: 12),
|
||||||
TextField(
|
TextField(
|
||||||
// onSubmitted: (loc) => {_searchLocation2(loc)},
|
|
||||||
controller: _locationController,
|
controller: _locationController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Enter location',
|
labelText: 'Search location',
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: const Icon(Icons.search),
|
icon: const Icon(Icons.search),
|
||||||
onPressed: _searchLocation,
|
onPressed: _searchLocation,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(height: 6),
|
||||||
Text(
|
Text(
|
||||||
errorText != null ? '$errorText' : '',
|
errorText != null ? '$errorText' : '',
|
||||||
style: const TextStyle(color: Colors.red),
|
style: const TextStyle(color: Colors.red),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ElevatedButton.icon(
|
|
||||||
icon: const Icon(Icons.my_location),
|
|
||||||
onPressed: _getCurrentLocation,
|
|
||||||
label: const Text('Current Position'),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Text('Country: $_country'),
|
Text('Country: $_country'),
|
||||||
Text('City: $_city'),
|
Text('City: $_city'),
|
||||||
Text('Postal Code: ${_postalCode ?? ''}'),
|
Text('Postal Code: ${_postalCode ?? ''}'),
|
||||||
|
@ -121,8 +121,6 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
nameDetails: true,
|
nameDetails: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
debugPrint(searchResult.single.address.toString()); // TODO remove
|
|
||||||
|
|
||||||
Map<String, dynamic>? addressData = searchResult.single.address;
|
Map<String, dynamic>? addressData = searchResult.single.address;
|
||||||
if (addressData != null) {
|
if (addressData != null) {
|
||||||
String street = _getStreetInfo(addressData);
|
String street = _getStreetInfo(addressData);
|
||||||
|
@ -195,10 +193,15 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
// Test if location services are enabled.
|
// Test if location services are enabled.
|
||||||
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
serviceEnabled = await Geolocator.isLocationServiceEnabled();
|
||||||
if (!serviceEnabled) {
|
if (!serviceEnabled) {
|
||||||
// Location services are not enabled don't continue
|
// Location services are not enabled, don't continue
|
||||||
// accessing the position and request users of the
|
// accessing the position and request users of the
|
||||||
// App to enable the location services.
|
// App to enable the location services.
|
||||||
return Future.error('Location services are disabled.');
|
setState(() {
|
||||||
|
errorText = 'Location services are disabled. '
|
||||||
|
'Enable location services and try again.';
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
permission = await Geolocator.checkPermission();
|
permission = await Geolocator.checkPermission();
|
||||||
|
@ -210,17 +213,23 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
// Android's shouldShowRequestPermissionRationale
|
// Android's shouldShowRequestPermissionRationale
|
||||||
// returned true. According to Android guidelines
|
// returned true. According to Android guidelines
|
||||||
// your App should show an explanatory UI now.
|
// your App should show an explanatory UI now.
|
||||||
return Future.error('Location permissions are denied');
|
setState(() {
|
||||||
|
errorText = 'Location permissions are denied';
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permission == LocationPermission.deniedForever) {
|
if (permission == LocationPermission.deniedForever) {
|
||||||
// Permissions are denied forever, handle appropriately.
|
// Permissions are denied forever, handle appropriately.
|
||||||
return Future.error(
|
setState(() {
|
||||||
'Location permissions are permanently denied, we cannot request permissions.');
|
errorText =
|
||||||
|
'Location permissions are permanently denied, cannot request permissions.';
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error getting location permission: $e');
|
errorText = 'Error getting location permission: $e';
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -229,8 +238,6 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
Position position = await Geolocator.getCurrentPosition(
|
Position position = await Geolocator.getCurrentPosition(
|
||||||
desiredAccuracy: LocationAccuracy.high);
|
desiredAccuracy: LocationAccuracy.high);
|
||||||
|
|
||||||
debugPrint(position.toString()); // TODO remove
|
|
||||||
|
|
||||||
if (isMobile) {
|
if (isMobile) {
|
||||||
// using package geocoding which works for Android and iOS only
|
// using package geocoding which works for Android and iOS only
|
||||||
List<Placemark> placeMarks = await placemarkFromCoordinates(
|
List<Placemark> placeMarks = await placemarkFromCoordinates(
|
||||||
|
@ -242,8 +249,10 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
_street = placeMark.street ?? '';
|
_street = placeMark.street ?? '';
|
||||||
_country = placeMark.country ?? '';
|
_country = placeMark.country ?? '';
|
||||||
_city = placeMark.locality ?? '';
|
_city = placeMark.locality ?? '';
|
||||||
|
_administrativeArea = placeMark.administrativeArea;
|
||||||
_latitude = position.latitude;
|
_latitude = position.latitude;
|
||||||
_longitude = position.longitude;
|
_longitude = position.longitude;
|
||||||
|
errorText = null;
|
||||||
});
|
});
|
||||||
triggerCallback();
|
triggerCallback();
|
||||||
}
|
}
|
||||||
|
@ -285,11 +294,11 @@ class LocationSelectorState extends State<LocationSelector> {
|
||||||
triggerCallback();
|
triggerCallback();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error looking up current location: $e');
|
errorText = 'Error looking up current location: $e';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error getting current location: $e');
|
errorText = 'Error getting current location: $e';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class TextWithBold extends StatelessWidget {
|
||||||
|
final String? leadingText;
|
||||||
|
final String boldText;
|
||||||
|
final String? trailingText;
|
||||||
|
|
||||||
|
const TextWithBold(
|
||||||
|
{super.key, this.leadingText, required this.boldText, this.trailingText});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
TextSpan(text: leadingText),
|
||||||
|
TextSpan(
|
||||||
|
text: boldText,
|
||||||
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
TextSpan(text: trailingText),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ class UserTileLikes extends StatelessWidget {
|
||||||
final DocumentSnapshot user;
|
final DocumentSnapshot user;
|
||||||
final bool hasMatch;
|
final bool hasMatch;
|
||||||
final VoidCallback onUnlike;
|
final VoidCallback onUnlike;
|
||||||
final VoidCallback onShowMatchMessage;
|
final VoidCallback onShowChat;
|
||||||
final VoidCallback onViewInfo;
|
final VoidCallback onViewInfo;
|
||||||
|
|
||||||
const UserTileLikes({
|
const UserTileLikes({
|
||||||
|
@ -15,7 +15,7 @@ class UserTileLikes extends StatelessWidget {
|
||||||
required this.user,
|
required this.user,
|
||||||
required this.hasMatch,
|
required this.hasMatch,
|
||||||
required this.onUnlike,
|
required this.onUnlike,
|
||||||
required this.onShowMatchMessage,
|
required this.onShowChat,
|
||||||
required this.onViewInfo,
|
required this.onViewInfo,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ class UserTileLikes extends StatelessWidget {
|
||||||
),
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: hasMatch
|
icon: hasMatch
|
||||||
? const Icon(Icons.lock_outline)
|
? const Icon(Icons.chat_outlined)
|
||||||
: const Icon(Icons.delete_outline, color: Colors.red),
|
: const Icon(Icons.delete_outline, color: Colors.red),
|
||||||
onPressed: hasMatch ? onShowMatchMessage : onUnlike,
|
onPressed: hasMatch ? onShowChat : onUnlike,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Constants {
|
||||||
/// Title of the app
|
/// Title of the app
|
||||||
static const String appTitle = 'Cofounderella';
|
static const String appTitle = 'Cofounderella';
|
||||||
static const String appVersion = '1.0.0';
|
static const String appVersion = '1.0.0';
|
||||||
static const String appCompilationDate = '2024-06-13';
|
static const String appCompilationDate = '2024-06-14';
|
||||||
|
|
||||||
static const String dbCollectionFeedbacks = 'feedbacks';
|
static const String dbCollectionFeedbacks = 'feedbacks';
|
||||||
static const String dbCollectionUsers = 'Users';
|
static const String dbCollectionUsers = 'Users';
|
||||||
|
|
|
@ -24,10 +24,8 @@ class ChatPage extends StatefulWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ChatPageState extends State<ChatPage> {
|
class _ChatPageState extends State<ChatPage> {
|
||||||
// text controller
|
|
||||||
final TextEditingController _messageController = TextEditingController();
|
final TextEditingController _messageController = TextEditingController();
|
||||||
|
|
||||||
// chat and auth services
|
|
||||||
final ChatService _chatService = ChatService();
|
final ChatService _chatService = ChatService();
|
||||||
final AuthService _authService = AuthService();
|
final AuthService _authService = AuthService();
|
||||||
|
|
||||||
|
@ -79,7 +77,9 @@ class _ChatPageState extends State<ChatPage> {
|
||||||
// send message if not empty
|
// send message if not empty
|
||||||
if (_messageController.text.isNotEmpty) {
|
if (_messageController.text.isNotEmpty) {
|
||||||
await _chatService.sendMessage(
|
await _chatService.sendMessage(
|
||||||
widget.receiverID, _messageController.text);
|
widget.receiverID,
|
||||||
|
_messageController.text,
|
||||||
|
);
|
||||||
|
|
||||||
// clear text controller
|
// clear text controller
|
||||||
_messageController.clear();
|
_messageController.clear();
|
||||||
|
@ -95,10 +95,7 @@ class _ChatPageState extends State<ChatPage> {
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
// display all messages
|
// display all messages
|
||||||
Expanded(
|
Expanded(child: _buildMessageList()),
|
||||||
child: _buildMessageList(),
|
|
||||||
),
|
|
||||||
|
|
||||||
// user input
|
// user input
|
||||||
_buildUserInput(),
|
_buildUserInput(),
|
||||||
],
|
],
|
||||||
|
@ -113,12 +110,12 @@ class _ChatPageState extends State<ChatPage> {
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
// errors
|
// errors
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Text("Error: ${snapshot.error}");
|
return Text('Error: ${snapshot.error}');
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading
|
// loading
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
return const Text("Loading..");
|
return const Text('Loading..');
|
||||||
}
|
}
|
||||||
|
|
||||||
// return list view
|
// return list view
|
||||||
|
@ -155,8 +152,8 @@ class _ChatPageState extends State<ChatPage> {
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
padding: const EdgeInsets.symmetric(horizontal: 25.0),
|
||||||
child: Text(
|
child: Text(
|
||||||
"${msgDate[0]} ${msgDate[1].substring(0, 5)}",
|
'${msgDate[0]} ${msgDate[1].substring(0, 5)}',
|
||||||
style: const TextStyle(color: Colors.grey),
|
style: const TextStyle(color: Colors.grey, fontSize: 10),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChatBubble(
|
ChatBubble(
|
||||||
|
|
|
@ -7,6 +7,7 @@ import '../enumerations.dart';
|
||||||
import '../models/swipe.dart';
|
import '../models/swipe.dart';
|
||||||
import '../services/auth/auth_service.dart';
|
import '../services/auth/auth_service.dart';
|
||||||
import '../utils/helper_dialogs.dart';
|
import '../utils/helper_dialogs.dart';
|
||||||
|
import 'chat_page.dart';
|
||||||
import 'user_profile_page.dart';
|
import 'user_profile_page.dart';
|
||||||
|
|
||||||
class LikedUsersPage extends StatefulWidget {
|
class LikedUsersPage extends StatefulWidget {
|
||||||
|
@ -100,26 +101,6 @@ class LikedUsersPageState extends State<LikedUsersPage> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showMatchMessage() {
|
|
||||||
showDialog(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) {
|
|
||||||
return AlertDialog(
|
|
||||||
title: const Text('Match Exists'),
|
|
||||||
content: const Text(
|
|
||||||
'You cannot unlike a user with whom you have a match.',
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.of(context).pop(),
|
|
||||||
child: const Text('Close'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool?> _showConfirmationDialog(String userId, String userName) async {
|
Future<bool?> _showConfirmationDialog(String userId, String userName) async {
|
||||||
bool? confirm = await showDialog<bool>(
|
bool? confirm = await showDialog<bool>(
|
||||||
context: context,
|
context: context,
|
||||||
|
@ -350,8 +331,19 @@ class LikedUsersPageState extends State<LikedUsersPage> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, //_unlikeUser(user.id),
|
},
|
||||||
onShowMatchMessage: _showMatchMessage,
|
onShowChat: () {
|
||||||
|
Navigator.push(
|
||||||
|
context,
|
||||||
|
MaterialPageRoute(
|
||||||
|
builder: (context) => ChatPage(
|
||||||
|
receiverEmail: user[Constants.dbFieldUsersEmail],
|
||||||
|
receiverID: user[Constants.dbFieldUsersID],
|
||||||
|
chatTitle: user[Constants.dbFieldUsersName],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
onViewInfo: () {
|
onViewInfo: () {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'package:swipable_stack/swipable_stack.dart';
|
||||||
|
|
||||||
import '../components/card_overlay.dart';
|
import '../components/card_overlay.dart';
|
||||||
import '../components/language_list.dart';
|
import '../components/language_list.dart';
|
||||||
|
import '../components/text_with_bold.dart';
|
||||||
import '../constants.dart';
|
import '../constants.dart';
|
||||||
import '../forms/matched_screen.dart';
|
import '../forms/matched_screen.dart';
|
||||||
import '../models/language.dart';
|
import '../models/language.dart';
|
||||||
|
@ -411,6 +412,14 @@ class UserMatchingPageState extends State<UserMatchingPage> {
|
||||||
|
|
||||||
String pronoun = getPronoun(userProfile.gender);
|
String pronoun = getPronoun(userProfile.gender);
|
||||||
|
|
||||||
|
String location =
|
||||||
|
userProfile.locations[Constants.dbDocMainLocation]?.toString() ?? 'N/A';
|
||||||
|
if (userProfile.locations.containsKey(Constants.dbDocSecondLocation) &&
|
||||||
|
userProfile.locations[Constants.dbDocSecondLocation] != null) {
|
||||||
|
location =
|
||||||
|
'$location and ${userProfile.locations[Constants.dbDocSecondLocation]?.toString() ?? 'N/A'}';
|
||||||
|
}
|
||||||
|
|
||||||
double shortDist =
|
double shortDist =
|
||||||
shortestDistanceBetweenUsers(currentUserProfile!, userProfile);
|
shortestDistanceBetweenUsers(currentUserProfile!, userProfile);
|
||||||
double matchScore = calculateMatchScore(currentUserProfile!, userProfile);
|
double matchScore = calculateMatchScore(currentUserProfile!, userProfile);
|
||||||
|
@ -435,10 +444,13 @@ class UserMatchingPageState extends State<UserMatchingPage> {
|
||||||
header: Text(
|
header: Text(
|
||||||
"${matchScore.toStringAsFixed(2)}%",
|
"${matchScore.toStringAsFixed(2)}%",
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontWeight: FontWeight.bold, fontSize: 16.0),
|
fontWeight: FontWeight.bold,
|
||||||
|
fontSize: 16.0,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
circularStrokeCap: CircularStrokeCap.round,
|
circularStrokeCap: CircularStrokeCap.round,
|
||||||
progressColor: _getProgressColor(matchScore),
|
progressColor: _getProgressColor(matchScore),
|
||||||
|
backgroundWidth: 2,
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 5, // Manually adjusted avatar position
|
bottom: 5, // Manually adjusted avatar position
|
||||||
|
@ -461,26 +473,35 @@ class UserMatchingPageState extends State<UserMatchingPage> {
|
||||||
Center(
|
Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
'${userProfile.name} ${ageInfo(userProfile.born)}'.trim(),
|
'${userProfile.name} ${ageInfo(userProfile.born)}'.trim(),
|
||||||
style: const TextStyle(fontSize: 24)),
|
style: const TextStyle(fontSize: 24),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
TextWithBold(
|
||||||
'Would like to team up with someone who has experience in '
|
leadingText:
|
||||||
'${userProfile.skillsSought.map((x) => x.displayName).join(', ')}.',
|
'Lives in $location which is ${shortDist <= 20 ? 'only ' : ''}about ',
|
||||||
|
boldText: '${shortDist.toStringAsFixed(0)} km',
|
||||||
|
trailingText: ' away from you.',
|
||||||
),
|
),
|
||||||
Text(
|
const SizedBox(height: 6),
|
||||||
'$pronoun brings skills and experience in '
|
TextWithBold(
|
||||||
'${userProfile.skills.map((x) => x.displayName).join(', ')}',
|
leadingText:
|
||||||
|
'Would like to team up with someone who has experience in ',
|
||||||
|
boldText: userProfile.skillsSought
|
||||||
|
.map((x) => x.displayName)
|
||||||
|
.join(', '),
|
||||||
|
trailingText: '.',
|
||||||
|
),
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
TextWithBold(
|
||||||
|
leadingText: '$pronoun brings skills and experience in ',
|
||||||
|
boldText:
|
||||||
|
userProfile.skills.map((x) => x.displayName).join(', '),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'and is willing to commit in '
|
'and is willing to commit in '
|
||||||
'${userProfile.availability.commitmentText}.',
|
'${userProfile.availability.commitmentText}.',
|
||||||
),
|
),
|
||||||
Text(
|
|
||||||
'Lives in ${userProfile.locations[Constants.dbDocMainLocation]?.toString() ?? 'N/A'}'
|
|
||||||
' and ${userProfile.locations[Constants.dbDocSecondLocation]?.toString() ?? 'N/A'}'
|
|
||||||
' which is ${shortDist <= 20 ? 'only ' : ''}about ${shortDist.toStringAsFixed(0)} km away from you.',
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
const Row(
|
const Row(
|
||||||
children: [
|
children: [
|
||||||
|
@ -510,14 +531,17 @@ class UserMatchingPageState extends State<UserMatchingPage> {
|
||||||
children: [
|
children: [
|
||||||
const Icon(Icons.person_search, size: 64),
|
const Icon(Icons.person_search, size: 64),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
const Text('You\'ve viewed all available profiles.',
|
const Text(
|
||||||
|
'You\'ve viewed all available profiles.',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
const SizedBox(height: 60),
|
const SizedBox(height: 60),
|
||||||
const Text(
|
const Text(
|
||||||
'Would you like to do another run and see the remaining profiles again?',
|
'Would you like to do another run and see the remaining profiles again?',
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
|
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:expandable_text/expandable_text.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:firebase_auth/firebase_auth.dart';
|
import 'package:firebase_auth/firebase_auth.dart';
|
||||||
|
|
||||||
|
@ -633,7 +634,17 @@ class _UserProfilePageState extends State<UserProfilePage> {
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(myData.bio ?? 'n/a', style: const TextStyle(fontSize: 16)),
|
ExpandableText(
|
||||||
|
linkEllipsis: false,
|
||||||
|
collapseOnTextTap: true,
|
||||||
|
expandOnTextTap: true,
|
||||||
|
myData.bio ?? 'n/a',
|
||||||
|
expandText: '[Expand]',
|
||||||
|
collapseText: '[Collapse]',
|
||||||
|
maxLines: 3,
|
||||||
|
linkColor: Colors.blue,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -105,6 +105,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.8"
|
version: "1.0.8"
|
||||||
|
expandable_text:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: expandable_text
|
||||||
|
sha256: "7d03ea48af6987b20ece232678b744862aa3250d4a71e2aaf1e4af90015d76b1"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -49,6 +49,7 @@ dependencies:
|
||||||
image_cropper: ^6.0.0
|
image_cropper: ^6.0.0
|
||||||
percent_indicator: ^4.2.3
|
percent_indicator: ^4.2.3
|
||||||
osm_nominatim: ^3.0.0
|
osm_nominatim: ^3.0.0
|
||||||
|
expandable_text: ^2.3.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
Loading…
Reference in New Issue