Skip to content

Commit 8650d50

Browse files
Fix bugs
1 parent 9ce1ea2 commit 8650d50

6 files changed

Lines changed: 67 additions & 38 deletions

File tree

lib/Screens/Detail/user_detail_screen.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ class _UserDetailScreenState extends State<UserDetailScreen>
129129
key: key2,
130130
userId: user!.restId!,
131131
nested: true,
132-
type: UserTweetFlowType.TweetsAndReplies,
132+
type: UserTweetFlowType.Replies,
133133
scrollController: primaryController,
134134
),
135135
),
@@ -424,7 +424,7 @@ class _UserDetailScreenState extends State<UserDetailScreen>
424424

425425
_buildMoreContextMenuButtons() {
426426
String screenName = userLegacy?.screenName ?? "";
427-
String url = userLegacy?.url ?? "https://twitter.com/$screenName";
427+
String url = "https://twitter.com/$screenName";
428428
return FlutterContextMenu(
429429
entries: [
430430
if (!isMyself && (userLegacy?.following ?? false))

lib/Screens/Flow/timeline_flow_screen.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import 'package:twitee/Models/view_config.dart';
1919
import 'package:twitee/Openapi/export.dart';
2020
import 'package:twitee/Utils/ilogger.dart';
2121
import 'package:twitee/Utils/itoast.dart';
22+
import 'package:twitee/Utils/utils.dart';
2223
import 'package:twitee/Widgets/General/EasyRefresh/easy_refresh.dart';
2324
import 'package:twitee/Widgets/Item/item_builder.dart';
2425
import 'package:twitee/Widgets/Twitter/post_item.dart';
@@ -83,7 +84,7 @@ class _TimelineFlowScreenState extends State<TimelineFlowScreen>
8384

8485
@override
8586
refreshViewConfig(ViewConfig viewConfig) async {
86-
await scrollToTop();
87+
// await scrollToTop();
8788
this.viewConfig = viewConfig;
8889
if (mounted) setState(() {});
8990
}
@@ -315,8 +316,8 @@ class _TimelineFlowScreenState extends State<TimelineFlowScreen>
315316
filteredEntries.length,
316317
(index) {
317318
return PostItem(
318-
key: GlobalObjectKey(
319-
filteredEntries[index].sortIndex.toString()),
319+
key: ValueKey(
320+
"${filteredEntries[index].sortIndex}_${Utils.generateUid()}"),
320321
entry: filteredEntries[index],
321322
feedbackActions:
322323
_getFeedBackActions(filteredEntries[index]),

lib/Screens/Flow/user_tweet_flow_screen.dart

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import 'package:twitee/Models/response_result.dart';
2020
import 'package:twitee/Openapi/export.dart';
2121
import 'package:twitee/Utils/ilogger.dart';
2222
import 'package:twitee/Utils/itoast.dart';
23+
import 'package:twitee/Utils/utils.dart';
2324
import 'package:twitee/Widgets/General/EasyRefresh/easy_refresh.dart';
2425
import 'package:twitee/Widgets/Item/item_builder.dart';
2526
import 'package:twitee/Widgets/Twitter/post_item.dart';
@@ -30,7 +31,7 @@ import '../../Resources/theme.dart';
3031
import '../../Utils/enums.dart';
3132
import '../../Utils/tweet_util.dart';
3233

33-
enum UserTweetFlowType { Tweets, Retweets, TweetsAndReplies, Highlights }
34+
enum UserTweetFlowType { Tweets, Retweets, Replies, Highlights }
3435

3536
class UserTweetFlowScreen extends StatefulWidgetForFlow {
3637
const UserTweetFlowScreen({
@@ -113,6 +114,7 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
113114
if (_loading) return;
114115
_loading = true;
115116
cursorBottom = null;
117+
bool reload = false;
116118
try {
117119
if (_initPhase != InitPhase.successful) {
118120
_initPhase = InitPhase.connecting;
@@ -126,7 +128,7 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
126128
userId: widget.userId,
127129
);
128130
break;
129-
case UserTweetFlowType.TweetsAndReplies:
131+
case UserTweetFlowType.Replies:
130132
res = await UserApi.getUserTweetsAndReplies(
131133
userId: widget.userId,
132134
);
@@ -152,16 +154,24 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
152154
.toList();
153155
}
154156
List<TimelineAddEntry> newEntries = [];
157+
bool hasResult = false;
155158
for (var instruction in timeline.instructions) {
156159
if (instruction is TimelinePinEntry) {
157160
pinEntry = instruction;
158161
}
159162
if (instruction is TimelineAddEntries) {
160-
newEntries = validEntries = _processEntries(instruction.entries);
163+
var tmp = _processEntries(instruction.entries);
164+
hasResult = tmp[0];
165+
newEntries = validEntries = tmp[1];
161166
_refreshCursor(instruction.entries);
162167
}
163168
}
164-
if (newEntries.isEmpty) {
169+
reload = hasResult && newEntries.isEmpty;
170+
if (reload) {
171+
_loading = false;
172+
return await _onLoad();
173+
}
174+
if (!hasResult && newEntries.isEmpty) {
165175
_noMore = true;
166176
} else {
167177
_noMore = false;
@@ -187,6 +197,7 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
187197
if (cursorBottom == null) return;
188198
if (_loading) return;
189199
_loading = true;
200+
bool reload = false;
190201
try {
191202
if (_initPhase != InitPhase.successful) {
192203
_initPhase = InitPhase.connecting;
@@ -201,7 +212,7 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
201212
cursorBottom: cursorBottom?.value,
202213
);
203214
break;
204-
case UserTweetFlowType.TweetsAndReplies:
215+
case UserTweetFlowType.Replies:
205216
res = await UserApi.getUserTweetsAndReplies(
206217
userId: widget.userId,
207218
cursorBottom: cursorBottom?.value,
@@ -229,17 +240,25 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
229240
.toList());
230241
}
231242
List<TimelineAddEntry> newEntries = [];
243+
bool hasResult = false;
232244
for (var instruction in timeline.instructions) {
233245
if (instruction is TimelinePinEntry) {
234246
pinEntry = instruction;
235247
}
236248
if (instruction is TimelineAddEntries) {
237-
validEntries.addAll(_processEntries(instruction.entries));
238-
newEntries = _processEntries(instruction.entries);
249+
var tmp = _processEntries(instruction.entries);
250+
hasResult = tmp[0];
251+
newEntries = tmp[1];
252+
validEntries.addAll(newEntries);
239253
_refreshCursor(instruction.entries);
240254
}
241255
}
242-
if (newEntries.isEmpty) {
256+
reload = hasResult && newEntries.isEmpty;
257+
if (reload) {
258+
_loading = false;
259+
return await _onLoad();
260+
}
261+
if (!hasResult && newEntries.isEmpty) {
243262
_noMore = true;
244263
return IndicatorResult.noMore;
245264
} else {
@@ -278,13 +297,15 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
278297

279298
_processEntries(List<TimelineAddEntry> entries) {
280299
List<TimelineAddEntry> result = [];
300+
bool hasResult = false;
281301
for (var entry in entries) {
282302
if (entry.content is TimelineTimelineItem &&
283303
(entry.content as TimelineTimelineItem).itemContent
284304
is TimelineTweet &&
285305
((entry.content as TimelineTimelineItem).itemContent as TimelineTweet)
286306
.promotedMetadata ==
287307
null) {
308+
hasResult = true;
288309
TimelineTweet tweet = (entry.content as TimelineTimelineItem)
289310
.itemContent as TimelineTweet;
290311
bool add = true;
@@ -298,12 +319,13 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
298319
} else if (entry.content is TimelineTimelineModule &&
299320
(entry.content as TimelineTimelineModule).displayType ==
300321
DisplayType.verticalConversation) {
301-
if (widget.type != UserTweetFlowType.Retweets) {
322+
hasResult = true;
323+
if (widget.type == UserTweetFlowType.Replies) {
302324
result.add(entry);
303325
}
304326
}
305327
}
306-
return result;
328+
return [hasResult, result];
307329
}
308330

309331
List<FeedbackActions> _getFeedBackActions(TimelineAddEntry entry) {
@@ -361,6 +383,8 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
361383
}
362384

363385
_buildMainBody() {
386+
bool addPin = pinEntry != null && widget.type == UserTweetFlowType.Tweets;
387+
bool hasContent = validEntries.isNotEmpty || addPin;
364388
return EasyRefresh.builder(
365389
onRefresh: () async {
366390
return await _onRefresh();
@@ -374,7 +398,7 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
374398
childBuilder: (context, pyhsics) => ItemBuilder.buildLoadMoreNotification(
375399
onLoad: _onLoad,
376400
noMore: _noMore,
377-
child: validEntries.isNotEmpty
401+
child: hasContent
378402
? WaterfallFlow.extent(
379403
physics: pyhsics,
380404
controller: widget.nested ? null : _scrollController,
@@ -383,22 +407,23 @@ class _UserTweetFlowScreenState extends State<UserTweetFlowScreen>
383407
crossAxisSpacing: MyTheme.responsiveCrossAxisSpacing,
384408
maxCrossAxisExtent: MyTheme.postMaxCrossAxisExtent,
385409
children: List.generate(
386-
validEntries.length + (pinEntry != null ? 1 : 0),
410+
validEntries.length + (addPin ? 1 : 0),
387411
(index) {
388-
if (pinEntry != null && index == 0) {
412+
if (addPin && index == 0) {
389413
return PostItem(
390-
key: const GlobalObjectKey("Pinned"),
414+
key: ValueKey("Pinned_${Utils.generateUid()}"),
391415
entry: pinEntry!.entry,
392416
feedbackActions: _getFeedBackActions(pinEntry!.entry),
393417
);
394418
} else {
395-
if (pinEntry != null) index -= 1;
419+
int trueIndex = index;
420+
if (addPin) trueIndex -= 1;
396421
return PostItem(
397-
key: GlobalObjectKey(
398-
validEntries[index].sortIndex.toString()),
399-
entry: validEntries[index],
422+
key: ValueKey(
423+
"${validEntries[trueIndex].sortIndex}_${Utils.generateUid()}"),
424+
entry: validEntries[trueIndex],
400425
feedbackActions:
401-
_getFeedBackActions(validEntries[index]),
426+
_getFeedBackActions(validEntries[trueIndex]),
402427
);
403428
}
404429
},

lib/Widgets/Hidable/scroll_to_hide.dart

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -189,17 +189,19 @@ class ScrollToHideState extends State<ScrollToHide>
189189
}
190190

191191
void listen() {
192-
if (widget.enabled) {
193-
if (widget.scrollControllers.any((element) =>
194-
element.hasClients &&
195-
element.position.userScrollDirection == ScrollDirection.forward)) {
196-
show();
197-
} else if (widget.scrollControllers.any((element) =>
198-
element.hasClients &&
199-
element.position.userScrollDirection == ScrollDirection.reverse &&
200-
element.position.pixels >= widget.triggerOffset)) {
201-
hide();
192+
try {
193+
if (widget.enabled) {
194+
if (widget.scrollControllers.any((element) =>
195+
element.hasClients &&
196+
element.position.userScrollDirection == ScrollDirection.forward)) {
197+
show();
198+
} else if (widget.scrollControllers.any((element) =>
199+
element.hasClients &&
200+
element.position.userScrollDirection == ScrollDirection.reverse &&
201+
element.position.pixels >= widget.triggerOffset)) {
202+
hide();
203+
}
202204
}
203-
}
205+
} catch (_) {}
204206
}
205207
}

lib/Widgets/WaterfallFlow/extended_list_library.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,6 @@ mixin ExtendedRenderObjectMixin on RenderSliverMultiBoxAdaptor {
226226
assert(child.parent == this);
227227
final SliverMultiBoxAdaptorParentData childParentData =
228228
child.parentData as SliverMultiBoxAdaptorParentData;
229-
return childParentData.layoutOffset! + closeToTrailingDistance;
229+
return childParentData.layoutOffset ?? 0 + closeToTrailingDistance;
230230
}
231231
}

lib/Widgets/WaterfallFlow/sliver_waterfall_flow.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ class RenderSliverWaterfallFlow extends RenderSliverMultiBoxAdaptor
434434
// Find the last child that is at or before the scrollOffset.
435435
earliestUsefulChild = firstChild;
436436

437-
if (crossAxisChildrenData.maxLeadingLayoutOffset! > scrollOffset) {
437+
if ((crossAxisChildrenData.maxLeadingLayoutOffset ?? 0) > scrollOffset) {
438438
RenderBox? child = firstChild;
439439
// Add children from min index to max index of leading to
440440
// make sure indexes are continuous.
@@ -449,7 +449,8 @@ class RenderSliverWaterfallFlow extends RenderSliverMultiBoxAdaptor
449449
child = childBefore(child);
450450
}
451451

452-
while (crossAxisChildrenData.maxLeadingLayoutOffset! > scrollOffset) {
452+
while (
453+
(crossAxisChildrenData.maxLeadingLayoutOffset ?? 0) > scrollOffset) {
453454
// We have to add children before the earliestUsefulChild.
454455
earliestUsefulChild =
455456
insertAndLayoutLeadingChild(childConstraints, parentUsesSize: true);

0 commit comments

Comments
 (0)