Skip to content

Commit 793f710

Browse files
authored
Merge pull request #297 from Manuito83/develop
Merge for v3.6.2
2 parents 70e6951 + dcb739a commit 793f710

File tree

8 files changed

+108
-49
lines changed

8 files changed

+108
-49
lines changed

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ if (localPropertiesFile.exists()) {
1616

1717
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
1818
if (flutterVersionCode == null) {
19-
flutterVersionCode = '465'
19+
flutterVersionCode = '466'
2020
}
2121

2222
def flutterVersionName = localProperties.getProperty('flutter.versionName')
2323
if (flutterVersionName == null) {
24-
flutterVersionName = '3.6.1'
24+
flutterVersionName = '3.6.2'
2525
}
2626

2727
def keystoreProperties = new Properties()

ios/Runner.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@
549549
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
550550
CODE_SIGN_IDENTITY = "Apple Development";
551551
CODE_SIGN_STYLE = Automatic;
552-
CURRENT_PROJECT_VERSION = 465;
552+
CURRENT_PROJECT_VERSION = 466;
553553
DEVELOPMENT_ASSET_PATHS = "";
554554
DEVELOPMENT_TEAM = 53KVJRJS99;
555555
ENABLE_BITCODE = NO;
@@ -567,7 +567,7 @@
567567
"$(inherited)",
568568
"$(PROJECT_DIR)/Flutter",
569569
);
570-
MARKETING_VERSION = 3.6.1;
570+
MARKETING_VERSION = 3.6.2;
571571
PRODUCT_BUNDLE_IDENTIFIER = com.manuito.tornpda;
572572
PRODUCT_NAME = "$(TARGET_NAME)";
573573
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -698,7 +698,7 @@
698698
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
699699
CODE_SIGN_IDENTITY = "Apple Development";
700700
CODE_SIGN_STYLE = Automatic;
701-
CURRENT_PROJECT_VERSION = 465;
701+
CURRENT_PROJECT_VERSION = 466;
702702
DEVELOPMENT_ASSET_PATHS = "";
703703
DEVELOPMENT_TEAM = 53KVJRJS99;
704704
ENABLE_BITCODE = NO;
@@ -716,7 +716,7 @@
716716
"$(inherited)",
717717
"$(PROJECT_DIR)/Flutter",
718718
);
719-
MARKETING_VERSION = 3.6.1;
719+
MARKETING_VERSION = 3.6.2;
720720
PRODUCT_BUNDLE_IDENTIFIER = com.manuito.tornpda;
721721
PRODUCT_NAME = "$(TARGET_NAME)";
722722
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -739,7 +739,7 @@
739739
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
740740
CODE_SIGN_IDENTITY = "Apple Development";
741741
CODE_SIGN_STYLE = Automatic;
742-
CURRENT_PROJECT_VERSION = 465;
742+
CURRENT_PROJECT_VERSION = 466;
743743
DEVELOPMENT_ASSET_PATHS = "";
744744
DEVELOPMENT_TEAM = 53KVJRJS99;
745745
ENABLE_BITCODE = NO;
@@ -757,7 +757,7 @@
757757
"$(inherited)",
758758
"$(PROJECT_DIR)/Flutter",
759759
);
760-
MARKETING_VERSION = 3.6.1;
760+
MARKETING_VERSION = 3.6.2;
761761
PRODUCT_BUNDLE_IDENTIFIER = com.manuito.tornpda;
762762
PRODUCT_NAME = "$(TARGET_NAME)";
763763
PROVISIONING_PROFILE_SPECIFIER = "";

lib/main.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,9 @@ import 'package:wakelock_plus/wakelock_plus.dart';
6868
import 'package:workmanager/workmanager.dart';
6969

7070
// TODO (App release)
71-
const String appVersion = '3.6.1';
72-
const String androidCompilation = '465';
73-
const String iosCompilation = '465';
71+
const String appVersion = '3.6.2';
72+
const String androidCompilation = '466';
73+
const String iosCompilation = '466';
7474

7575
// TODO (App release)
7676
// Note: if using Windows and calling HTTP functions, we need to change the URL in [firebase_functions.dart]

lib/utils/changelog.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,12 @@ class ChangeLogState extends State<ChangeLog> {
5151
void _createItems() {
5252
final itemList = <ChangeLogItem>[];
5353

54-
// v3.6.1 - Build 465 - 06/11/2024
54+
// v3.6.2 - Build 466 - 07/11/2024
5555
itemList.add(
5656
ChangeLogItem()
57-
..version = 'Torn PDA v3.6.1'
57+
..version = 'Torn PDA v3.6.2'
5858
..date = '8 DEC 2024'
59+
..infoString = 'Hotfix: resolved an issue affecting the reordering of tabs'
5960
..features = [
6061
"Added channel info to chat notifications",
6162
"Fixed notifications for own chat messages",

lib/utils/stats_calculator.dart

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:developer';
2+
13
class StatsCalculator {
24
static final statsLevelTriggers = [2, 6, 11, 26, 31, 50, 71, 100];
35
static final statsCrimesTriggers = [100, 5000, 10000, 20000, 30000, 50000];
@@ -48,19 +50,23 @@ class StatsCalculator {
4850
required int? networth,
4951
required String? rank,
5052
}) {
51-
final levelIndex = statsLevelTriggers.lastIndexWhere((x) => x <= level!) + 1;
52-
final crimeIndex = statsCrimesTriggers.lastIndexWhere((x) => x <= criminalRecordTotal!) + 1;
53-
final networthIndex = statsNetworthTriggers.lastIndexWhere((x) => x <= networth!) + 1;
54-
var rankIndex = 0;
55-
statsRanksTriggers.forEach((tornRank, index) {
56-
if (rank!.contains(tornRank)) {
57-
rankIndex = index;
58-
}
59-
});
53+
try {
54+
final levelIndex = statsLevelTriggers.lastIndexWhere((x) => x <= level!) + 1;
55+
final crimeIndex = statsCrimesTriggers.lastIndexWhere((x) => x <= criminalRecordTotal!) + 1;
56+
final networthIndex = statsNetworthTriggers.lastIndexWhere((x) => x <= networth!) + 1;
57+
var rankIndex = 0;
58+
statsRanksTriggers.forEach((tornRank, index) {
59+
if (rank!.contains(tornRank)) {
60+
rankIndex = index;
61+
}
62+
});
6063

61-
final finalIndex = rankIndex - levelIndex - crimeIndex - networthIndex - 1;
62-
if (finalIndex >= 0 && finalIndex <= 6) {
63-
return statsResults[finalIndex];
64+
final finalIndex = rankIndex - levelIndex - crimeIndex - networthIndex - 1;
65+
if (finalIndex >= 0 && finalIndex <= 6) {
66+
return statsResults[finalIndex];
67+
}
68+
} catch (e) {
69+
log(e.toString());
6470
}
6571
return "unk";
6672
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
2+
import 'package:html/parser.dart';
3+
4+
class WebViewUtils {
5+
/// Checks for a specific element by [selector] in the HTML from [webViewController]
6+
/// It will attempt to find the element(s) up to [maxSeconds] total, checking every [intervalSeconds]
7+
///
8+
/// If [returnElements] is true, it returns a tuple-like result:
9+
/// {
10+
/// 'document': dom.Document,
11+
/// 'elements': List<dom.Element>
12+
/// }
13+
///
14+
/// Otherwise, it only returns the [dom.Document]
15+
///
16+
/// If the element is never found, returns null
17+
static Future<Map<String, dynamic>?> waitForElement({
18+
required InAppWebViewController webViewController,
19+
required String selector,
20+
int maxSeconds = 6,
21+
int intervalSeconds = 1,
22+
bool returnElements = false,
23+
}) async {
24+
final int attempts = (maxSeconds / intervalSeconds).ceil();
25+
26+
for (int attempt = 0; attempt < attempts; attempt++) {
27+
await Future.delayed(Duration(seconds: intervalSeconds));
28+
29+
final html = await webViewController.getHtml();
30+
final document = parse(html);
31+
final elements = document.querySelectorAll(selector);
32+
33+
if (elements.isNotEmpty) {
34+
if (returnElements) {
35+
return {'document': document, 'elements': elements};
36+
} else {
37+
return {'document': document};
38+
}
39+
}
40+
}
41+
42+
return null;
43+
}
44+
}

lib/widgets/webviews/circular_menu/circular_menu_tabs.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class CircularMenuTabsState extends State<CircularMenuTabs> with SingleTickerPro
138138
if (!mounted) return;
139139
_onTabTapped(context);
140140
},
141-
child: ReorderableDragStartListener(
141+
child: ReorderableDelayedDragStartListener(
142142
index: widget.tabIndex,
143143
child: Container(
144144
alignment: Alignment.center,

lib/widgets/webviews/webview_full.dart

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import 'package:torn_pda/torn-pda-native/auth/native_user_provider.dart';
6464
import 'package:torn_pda/utils/html_parser.dart' as pda_parser;
6565
import 'package:torn_pda/utils/js_snippets.dart';
6666
import 'package:torn_pda/utils/shared_prefs.dart';
67+
import 'package:torn_pda/utils/webview/webview_utils.dart';
6768
import 'package:torn_pda/widgets/bounties/bounties_widget.dart';
6869
import 'package:torn_pda/widgets/chaining/chain_widget.dart';
6970
import 'package:torn_pda/widgets/city/city_widget.dart';
@@ -2838,7 +2839,9 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
28382839
_cityTriggered = false;
28392840
_profileTriggered = false;
28402841
_attackTriggered = false;
2841-
} else if (_currentUrl.contains("torn.com/profiles.php?XID=") && _profileTriggered) {
2842+
} else if ((_currentUrl.contains("torn.com/profiles.php?XID=") ||
2843+
_currentUrl.contains("torn.com/profiles.php?NID=")) &&
2844+
_profileTriggered) {
28422845
_crimesTriggered = false;
28432846
_gymTriggered = false;
28442847
_vaultTriggered = false;
@@ -4007,7 +4010,7 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
40074010
}
40084011

40094012
// ASSESS PROFILES
4010-
Future _assessProfileAttack({dom.Document? document, String pageTitle = ""}) async {
4013+
Future _assessProfileAttack({required dom.Document document, String pageTitle = ""}) async {
40114014
if (mounted) {
40124015
if (!_currentUrl.contains('loader.php?sid=attack&user2ID=') &&
40134016
!_currentUrl.contains('loader2.php?sid=getInAttack&user2ID=') &&
@@ -4046,29 +4049,34 @@ class WebViewFullState extends State<WebViewFull> with WidgetsBindingObserver {
40464049
// When the URL is constructed with name instead of ID (e.g.: when the heart icon is pressed),
40474050
// we capture the ID from the profile element, ensuring that it's besides the correct name
40484051

4049-
final RegExp regId = RegExp(r"php\?NID=([^&]+)");
4050-
final matches = regId.allMatches(_currentUrl);
4051-
final String username = matches.elementAt(0).group(1)!;
4052+
final result = await WebViewUtils.waitForElement(
4053+
webViewController: webViewController!,
4054+
selector: 'a.profile-image-wrapper[href*="XID="]',
4055+
maxSeconds: 6,
4056+
intervalSeconds: 1,
4057+
returnElements: true,
4058+
);
40524059

4053-
final dom.Element userInfoValue = document!.querySelector('div.user-info-value')!;
4054-
final String textContent = userInfoValue.querySelector('span.bold')!.text.trim();
4055-
final RegExp regUsername = RegExp('($username' r')\s*\[([0-9]+)\]');
4056-
final match = regUsername.firstMatch(textContent);
4057-
if (match != null) {
4058-
setState(() {
4059-
_profileAttackWidget = ProfileAttackCheckWidget(
4060-
key: UniqueKey(),
4061-
profileId: int.parse(match.group(2)!),
4062-
apiKey: _userProvider?.basic?.userApiKey ?? "",
4063-
profileCheckType: ProfileCheckType.profile,
4064-
themeProvider: _themeProvider,
4065-
);
4066-
});
4067-
}
4068-
} else {
4069-
userId = 0;
4060+
if (result == null) throw ("No html tag found");
4061+
4062+
document = result['document'] as dom.Document;
4063+
final elements = result['elements'] as List<dom.Element>;
4064+
final anchor = elements.first;
4065+
final match = RegExp(r"XID=([^&]+)").firstMatch(anchor.attributes['href']!)!;
4066+
userId = int.parse(match.group(1)!);
4067+
4068+
setState(() {
4069+
_profileAttackWidget = ProfileAttackCheckWidget(
4070+
key: UniqueKey(),
4071+
profileId: userId,
4072+
apiKey: _userProvider?.basic?.userApiKey ?? "",
4073+
profileCheckType: ProfileCheckType.profile,
4074+
themeProvider: _themeProvider,
4075+
);
4076+
});
40704077
}
4071-
} catch (e) {
4078+
} catch (e, trace) {
4079+
log("Issue locating NID user ID: $e, $trace", name: "Profile Check");
40724080
userId = 0;
40734081
}
40744082
} else if (_currentUrl.contains('loader.php?sid=attack&user2ID=') ||

0 commit comments

Comments
 (0)