Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
## [1.3.0-beta](https://github.com/DrSolidDevil/Vidar/compare/v1.2.2-beta...v1.3.0-beta) (2025-08-17)

> This version of Vidar brings you quality of life and performance improvements.

### New Features
* Added option to display time using the 12-hour clock (a.m./p.m.). [`3ed6a35`](https://github.com/DrSolidDevil/Vidar/commit/3ed6a35010102d115f21d0e8af6b498ecff332b9)
* You will now be prompted sometimes to give feedback. This feedback is sent via mail. This request for feedback can be disabled in settings. [`95d8987`](https://github.com/DrSolidDevil/Vidar/commit/95d89875bc9ae195b267ad7b309beb7a1e8ec5d8) [`1c505ae`](https://github.com/DrSolidDevil/Vidar/commit/1c505ae314404842ecf8794e413ac9b7b788578a)

### Performance Improvements
* Rewrote message querying and rendering to be able to handle long conversations much better. [`22e1c12`](https://github.com/DrSolidDevil/Vidar/commit/22e1c126905036c7dbd16ec0d2fd16f25d662a83)
* Rewrote the SMS permission request to utilize `FutureBuilder`. [`22e1c12`](https://github.com/DrSolidDevil/Vidar/commit/22e1c126905036c7dbd16ec0d2fd16f25d662a83) [`43a087b`](https://github.com/DrSolidDevil/Vidar/commit/43a087b6cf696e5c747d59a24f88fb342bdeaac6)

### Other Changes
* Message bar now expands when writing a long/multiline message. When the message is to long for the additional lines visible on screen then it starts to scroll. This feature makes you able to write long messages without headache. [`2a7a750`](https://github.com/DrSolidDevil/Vidar/commit/2a7a750df0a29ddc121ac5b15a1ab34ae5a7c086)
* Dialogs/popups now scroll when its text is very long. [`2a7a750`](https://github.com/DrSolidDevil/Vidar/commit/2a7a750df0a29ddc121ac5b15a1ab34ae5a7c086)
* Added scrollbar to settings page. [`2d6e222`](https://github.com/DrSolidDevil/Vidar/commit/2d6e22202cb1dc56613713e17a61844a006fc38f)
* Visual improvements. [`bab8afd`](https://github.com/DrSolidDevil/Vidar/commit/bab8afdc284a7cf5e0f259a7d6b5bf392fd4212c) [`f54f40b`](https://github.com/DrSolidDevil/Vidar/commit/f54f40b2cc98ca2def8d031c707ca42749e12011)
* Updated screenshots [`7620b55`](https://github.com/DrSolidDevil/Vidar/commit/7620b55f699dfa3288634938542fe71682467f3d)

<br>

## [1.2.2-beta](https://github.com/DrSolidDevil/Vidar/compare/v1.2.1-beta...v1.2.2-beta) (2025-08-02)

> Bug fix on the edit contact page.
Expand Down
8 changes: 8 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

<queries>
<!-- If your app opens https URLs -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="mailto" />
</intent>
</queries>

<application
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class MainActivity : FlutterActivity() {
).setMethodCallHandler { call, result ->
when (call.method) {
"querySms" -> {
result.success(querySms(context, call.argument("phoneNumber")))
result.success(querySms(context, call.argument("phoneNumber"), call.argument("latestN")))
}

"sendSms" -> {
Expand Down
21 changes: 16 additions & 5 deletions android/app/src/main/kotlin/com/drsoliddevil/vidar/SmsQuery.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,29 @@ import androidx.core.net.toUri
import android.provider.Telephony.TextBasedSmsColumns


fun querySms(context: Context, phoneNumber: String?): ArrayList<HashMap<String, String>>? {
fun querySms(context: Context, phoneNumber: String?, latestN: Int?): ArrayList<HashMap<String, String>>? {
val sms: Cursor?
if (phoneNumber != null) {
sms = context.contentResolver.query(
"content://sms/".toUri(),
includedQueryData,
"address=?",
arrayOf(phoneNumber),
null
"${TextBasedSmsColumns.DATE} DESC" // Latest message first
)
} else {
sms = context.contentResolver.query(
"content://sms/".toUri(),
includedQueryData,
null,
null,
null
"${TextBasedSmsColumns.DATE} DESC" // Latest message first
)
}
if (sms == null || !sms.moveToFirst()) {
return null
}
return cursorToListOfHashMap(sms)
return cursorToListOfHashMap(sms, latestN)
}

private val includedQueryData: Array<String> = arrayOf(
Expand All @@ -49,7 +49,7 @@ private val includedQueryData: Array<String> = arrayOf(

// Closes the cursor when it's done
// A list of hashmaps in kotlin is equivalent to a list of maps in dart
private fun cursorToListOfHashMap(cursor: Cursor): ArrayList<HashMap<String, String>> {
private fun cursorToListOfHashMap(cursor: Cursor, latestN: Int?): ArrayList<HashMap<String, String>> {
val threadIdColumnIndex: Int = cursor.getColumnIndexOrThrow(TextBasedSmsColumns.THREAD_ID)
val typeColumnIndex: Int = cursor.getColumnIndexOrThrow(TextBasedSmsColumns.TYPE)
val addressColumnIndex: Int = cursor.getColumnIndexOrThrow(TextBasedSmsColumns.ADDRESS)
Expand All @@ -64,9 +64,20 @@ private fun cursorToListOfHashMap(cursor: Cursor): ArrayList<HashMap<String, Str
val bodyColumnIndex: Int = cursor.getColumnIndexOrThrow(TextBasedSmsColumns.BODY)
val hashMapList: ArrayList<HashMap<String, String>> = ArrayList<HashMap<String, String>>()

var i: Int = 0
println("latestN = $latestN")
@Suppress("ConvertTryFinallyToUseCall")
try {
do {
println(i)
if (latestN != null) {
if (i >= latestN) {
break
} else {
++i
}
}

val entry: MutableMap<String, String> = mutableMapOf<String, String>()
entry[TextBasedSmsColumns.THREAD_ID] = cursor.getString(threadIdColumnIndex)
entry[TextBasedSmsColumns.TYPE] = cursor.getString(typeColumnIndex)
Expand Down
1 change: 1 addition & 0 deletions devtools_options.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions:
- shared_preferences: true
14 changes: 14 additions & 0 deletions lib/configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class SizeConfiguration {
static const double messageVerticalSeperation = 5;
static const double settingInfoText = 12;
static const double loadingFontSize = 32;
static const double feedbackFormFontSize = 12;
}

class TimeConfiguration {
Expand All @@ -36,6 +37,17 @@ class TimeConfiguration {
}

class MiscellaneousConfiguration {
// Probability of the user seeing a dialog prompting them to give feedback 0-1,
// where 1 means showing it always.
static const double userFeedbackDialogProbability = 0.0065; // 0.65% chance
static const Duration userFeedbackDialogPopupWait = const Duration(
seconds: 1,
);
static const String userFeedbackEmailAddress =
"drsoliddevil+vidarfeedback@gmail.com";
}

class ChatConfiguration {
static const String errorPrefix = "⚠";
static const List<String> messageHints = <String>[
"Write them a message!",
Expand All @@ -44,6 +56,8 @@ class MiscellaneousConfiguration {
"Start gossiping...",
"Talk to them, they miss you.",
];
// Number of messages to check during chat update
static const int numCheckDuringUpdate = 5;
}

class LoggingConfiguration {
Expand Down
41 changes: 30 additions & 11 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ import "package:permission_handler/permission_handler.dart";
import "package:shared_preferences/shared_preferences.dart";
import "package:vidar/configuration.dart";
import "package:vidar/pages/contact_list.dart";
import "package:vidar/pages/no_sms_permission.dart";
import "package:vidar/utils/common_object.dart";
import "package:vidar/utils/settings.dart";
import "package:vidar/utils/sms.dart";
import "package:vidar/utils/storage.dart";

late PermissionStatus smsStatus;
import "package:vidar/widgets/info_text_widget.dart";

void main() async {
WidgetsFlutterBinding.ensureInitialized();
Expand All @@ -31,7 +29,6 @@ void main() async {
wipeSecureStorage();
}
SmsConstants(await retrieveSmsConstantsMap());
smsStatus = await Permission.sms.request();
CommonObject.lastLogon = DateTime.now();
await (await SharedPreferences.getInstance()).setString(
"lastlogon",
Expand All @@ -45,11 +42,33 @@ class VidarApp extends StatelessWidget {
const VidarApp({super.key});

@override
Widget build(final BuildContext context) {
if (smsStatus.isGranted) {
return const MaterialApp(title: "Vidar", home: ContactListPage());
} else {
return const MaterialApp(title: "Vidar", home: NoSmsPermissionPage());
}
}
Widget build(final BuildContext context) => MaterialApp(
title: "Vidar",
home: FutureBuilder<PermissionStatus>(
future: Permission.sms.request(),
builder:
(
final BuildContext context,
final AsyncSnapshot<PermissionStatus> snapshot,
) {
if (snapshot.hasData) {
if (snapshot.data!.isGranted) {
return const ContactListPage();
} else {
return const InfoText(
text:
"To use Vidar you need to enable SMS permissions. Enable SMS permissions in the app settings then restart the app.",
textWidthFactor: 0.8,
fontSize: 20,
);
}
} else {
return const InfoText(
text: "Requesting SMS permission",
textWidthFactor: 0.8,
);
}
},
),
);
}
Loading