generated from Fedodo/Fedodo.README.Template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🔀 Merge pull request #29 from Fedodo/dev
Dev
- Loading branch information
Showing
7 changed files
with
377 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import 'package:flutter/material.dart'; | ||
import 'package:flutter_html/flutter_html.dart'; | ||
import 'package:url_launcher/url_launcher.dart'; | ||
|
||
class ProfileDescription extends StatelessWidget { | ||
const ProfileDescription({ | ||
Key? key, | ||
this.htmlData, | ||
}) : super(key: key); | ||
|
||
final String? htmlData; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
return Html( | ||
data: htmlData ?? "", | ||
style: { | ||
"p": Style(fontSize: FontSize(16)), | ||
"a": Style( | ||
fontSize: FontSize(16), | ||
textDecoration: TextDecoration.none, | ||
), | ||
}, | ||
extensions: [ | ||
TagExtension( | ||
tagsToExtend: {"a"}, | ||
builder: (extensionContext) { | ||
return InkWell( | ||
onTap: () => { | ||
launchUrl( | ||
Uri.parse( | ||
extensionContext.element!.attributes["href"]!, | ||
), | ||
), | ||
}, | ||
child: Text( | ||
extensionContext.node.text!, | ||
style: const TextStyle( | ||
color: Colors.blue, | ||
fontSize: 16, | ||
), | ||
), | ||
); | ||
}, | ||
), | ||
], | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import 'package:activitypub/activitypub.dart'; | ||
import 'package:fedodo_general/widgets/profile/enums/profile_button_state.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
class ProfileNameRow extends StatefulWidget { | ||
const ProfileNameRow({ | ||
Key? key, | ||
required this.preferredUsername, | ||
required this.userId, | ||
required this.name, | ||
required this.profileButtonInitialState, | ||
}) : super(key: key); | ||
|
||
final String preferredUsername; | ||
final String userId; | ||
final String? name; | ||
final Future<ProfileButtonState> profileButtonInitialState; | ||
|
||
@override | ||
State<ProfileNameRow> createState() => _ProfileNameRowState(); | ||
} | ||
|
||
class _ProfileNameRowState extends State<ProfileNameRow> { | ||
late Future<ProfileButtonState> profileButtonState; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
|
||
profileButtonState = widget.profileButtonInitialState; | ||
|
||
String fullUserName = | ||
"@${widget.preferredUsername}@${Uri.parse(widget.userId).authority}"; | ||
|
||
return Padding( | ||
padding: const EdgeInsets.all(8), | ||
child: Row( | ||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||
children: [ | ||
Column( | ||
crossAxisAlignment: CrossAxisAlignment.start, | ||
children: [ | ||
Text( | ||
widget.name ?? "", | ||
style: const TextStyle( | ||
fontSize: 25, | ||
fontWeight: FontWeight.bold, | ||
), | ||
), | ||
Text( | ||
fullUserName, | ||
style: const TextStyle( | ||
fontSize: 13, | ||
fontWeight: FontWeight.bold, | ||
color: Colors.white54, | ||
), | ||
), | ||
], | ||
), | ||
Column( | ||
children: [ | ||
FutureBuilder<ProfileButtonState>( | ||
future: profileButtonState, | ||
builder: (BuildContext context, | ||
AsyncSnapshot<ProfileButtonState> snapshot) { | ||
Widget child; | ||
if (snapshot.hasData) { | ||
switch (snapshot.data!) { | ||
case ProfileButtonState.ownProfile: | ||
{ | ||
child = ElevatedButton( | ||
onPressed: () {}, | ||
child: const Text("Edit Profile"), | ||
); | ||
} | ||
break; | ||
case ProfileButtonState.subscribed: | ||
{ | ||
child = ElevatedButton( | ||
onPressed: () {}, | ||
child: const Text("Unfollow"), | ||
); | ||
} | ||
break; | ||
case ProfileButtonState.notSubscribed: | ||
child = ElevatedButton( | ||
onPressed: () async { | ||
ActivityAPI activityApi = ActivityAPI(); | ||
activityApi.follow(Uri.parse(widget.userId)); | ||
|
||
setState(() { | ||
profileButtonState = Future.sync( | ||
() => ProfileButtonState.subscribed); | ||
}); | ||
}, | ||
child: const Text("Follow"), | ||
); | ||
break; | ||
} | ||
} else if (snapshot.hasError) { | ||
child = const Icon( | ||
Icons.error_outline, | ||
color: Colors.red, | ||
size: 60, | ||
); | ||
} else { | ||
child = ElevatedButton( | ||
onPressed: () {}, | ||
child: const Text("Loading"), | ||
); | ||
} | ||
return child; | ||
}, | ||
), | ||
], | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
lib/widgets/profile/components/profile_picture_detail.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import 'package:fedodo_general/Extensions/string_extensions.dart'; | ||
import 'package:flutter/material.dart'; | ||
|
||
class ProfilePictureDetail extends StatefulWidget { | ||
const ProfilePictureDetail({ | ||
Key? key, | ||
required this.followersCount, | ||
required this.followingCount, | ||
required this.postsCount, | ||
this.iconUrl, | ||
}) : super(key: key); | ||
|
||
final int followersCount; | ||
final int followingCount; | ||
final int postsCount; | ||
final String? iconUrl; | ||
|
||
@override | ||
State<ProfilePictureDetail> createState() => _ProfilePictureDetailState(); | ||
} | ||
|
||
class _ProfilePictureDetailState extends State<ProfilePictureDetail> { | ||
@override | ||
Widget build(BuildContext context) { | ||
return Padding( | ||
padding: const EdgeInsets.all(8.0), | ||
child: Row( | ||
children: [ | ||
Column( | ||
children: [ | ||
ClipRRect( | ||
borderRadius: BorderRadius.circular(15), | ||
child: Image.network( | ||
width: 80, | ||
height: 80, | ||
widget.iconUrl != null | ||
? widget.iconUrl!.asFedodoProxyString() | ||
: "https://upload.wikimedia.org/wikipedia/commons/8/89/Portrait_Placeholder.png?20170328184010" | ||
.asFedodoProxyString(), | ||
), | ||
), | ||
], | ||
), | ||
Expanded( | ||
child: Row( | ||
mainAxisAlignment: MainAxisAlignment.spaceAround, | ||
children: [ | ||
Column( | ||
children: [ | ||
Text( | ||
widget.postsCount.toString(), | ||
style: const TextStyle( | ||
fontSize: 20, | ||
fontWeight: FontWeight.bold, | ||
), | ||
), | ||
const Text("Posts"), | ||
], | ||
), | ||
Column( | ||
children: [ | ||
Text( | ||
widget.followingCount.toString(), | ||
style: const TextStyle( | ||
fontSize: 20, | ||
fontWeight: FontWeight.bold, | ||
), | ||
), | ||
const Text("Following"), | ||
], | ||
), | ||
Column( | ||
children: [ | ||
Text( | ||
widget.followersCount.toString(), | ||
style: const TextStyle( | ||
fontSize: 20, | ||
fontWeight: FontWeight.bold, | ||
), | ||
), | ||
const Text("Followers"), | ||
], | ||
), | ||
], | ||
), | ||
), | ||
], | ||
), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
enum ProfileButtonState { | ||
ownProfile, | ||
subscribed, | ||
notSubscribed | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import 'package:activitypub/APIs/followers_api.dart'; | ||
import 'package:activitypub/APIs/followings_api.dart'; | ||
import 'package:activitypub/APIs/outbox_api.dart'; | ||
import 'package:activitypub/Models/actor.dart'; | ||
import 'package:activitypub/Models/ordered_paged_collection.dart'; | ||
import 'package:fedodo_general/Globals/general.dart'; | ||
import 'package:flutter/material.dart'; | ||
import 'components/profile_description.dart'; | ||
import 'components/profile_name_row.dart'; | ||
import 'components/profile_picture_detail.dart'; | ||
import 'enums/profile_button_state.dart'; | ||
|
||
class ProfileHead extends StatefulWidget { | ||
const ProfileHead({ | ||
super.key, | ||
required this.actor, | ||
}); | ||
|
||
final Actor actor; | ||
|
||
@override | ||
State<ProfileHead> createState() => _ProfileHeadState(); | ||
} | ||
|
||
class _ProfileHeadState extends State<ProfileHead> { | ||
int? postCount; | ||
int? followingCount; | ||
int? followersCount; | ||
|
||
@override | ||
Widget build(BuildContext context) { | ||
if (followersCount == null && widget.actor.followers != null) { | ||
setFollowers(widget.actor.followers!); | ||
} | ||
if (followingCount == null && widget.actor.following != null) { | ||
setFollowings(widget.actor.following!); | ||
} | ||
if (postCount == null) { | ||
setPosts(widget.actor.outbox!); | ||
} | ||
|
||
return Column( | ||
children: [ | ||
ProfilePictureDetail( | ||
followersCount: followersCount ?? 0, | ||
followingCount: followingCount ?? 0, | ||
iconUrl: widget.actor.icon?.url, | ||
postsCount: postCount ?? 0, | ||
), | ||
ProfileNameRow( | ||
profileButtonInitialState: getProfileButtonState(widget.actor), | ||
preferredUsername: widget.actor.preferredUsername!, | ||
userId: widget.actor.id!, | ||
name: widget.actor.name, | ||
), | ||
ProfileDescription( | ||
htmlData: widget.actor.summary ?? "", | ||
), | ||
], | ||
); | ||
} | ||
|
||
Future<ProfileButtonState> getProfileButtonState(Actor actor) async { | ||
if (actor.id == null) General.logger.w("ActorId was null!"); | ||
|
||
if (actor.id == General.fullActorId) { | ||
return ProfileButtonState.ownProfile; | ||
} else { | ||
FollowingsAPI followingsAPI = FollowingsAPI(); | ||
var isFollowed = | ||
await followingsAPI.isFollowed(actor.id!, General.fullActorId); | ||
if (isFollowed) { | ||
return ProfileButtonState.subscribed; | ||
} else { | ||
return ProfileButtonState.notSubscribed; | ||
} | ||
} | ||
} | ||
|
||
void setFollowers(String followersString) async { | ||
FollowersAPI followersApi = FollowersAPI(); | ||
OrderedPagedCollection followersCollection = | ||
await followersApi.getFollowers(followersString); | ||
|
||
setState(() { | ||
followersCount = followersCollection.totalItems; | ||
}); | ||
} | ||
|
||
void setFollowings(String followingsString) async { | ||
FollowingsAPI followersProvider = FollowingsAPI(); | ||
OrderedPagedCollection followingCollection = | ||
await followersProvider.getFollowings(followingsString); | ||
|
||
setState(() { | ||
followingCount = followingCollection.totalItems; | ||
}); | ||
} | ||
|
||
void setPosts(String outboxUrl) async { | ||
OutboxAPI outboxProvider = OutboxAPI(); | ||
|
||
OrderedPagedCollection orderedPagedCollection = | ||
await outboxProvider.getFirstPage(outboxUrl); | ||
|
||
setState(() { | ||
postCount = orderedPagedCollection.totalItems; | ||
}); | ||
} | ||
} |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters