1
0
mirror of https://github.com/go-vikunja/app synced 2024-06-02 18:49:47 +00:00

added quicktile to add task quickly

This commit is contained in:
benimautner 2022-04-28 13:58:27 +02:00
parent 74069180fa
commit 7bc2157834
7 changed files with 180 additions and 22 deletions

View File

@ -47,6 +47,11 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
<meta-data
android:name="flutterEmbedding"
android:value="2" />
@ -54,6 +59,7 @@
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- If you want your foreground service to be stopped if
your app is stopped, set android:stopWithTask to true.
See https://developer.android.com/reference/android/R.attr#stopWithTask -->
@ -61,6 +67,21 @@
android:name="com.dexterous.flutterlocalnotifications.ForegroundService"
android:exported="false"
android:stopWithTask="false"/>
<service
android:name=".VikunjaTileService"
android:icon="@mipmap/ic_launcher"
android:label="Add Task"
android:exported="true"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action
android:name="android.service.quicksettings.action.QS_TILE"/>
</intent-filter>
<meta-data
android:name="android.service.quicksettings.ACTIVE_TILE"
android:value="true" />
</service>
</application>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
</manifest>

View File

@ -1,6 +1,63 @@
package io.vikunja.flutteringvikunja
import android.content.Intent
import android.content.Intent.getIntent
import android.os.Bundle
import io.flutter.plugins.GeneratedPluginRegistrant
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.util.Log
class MainActivity : FlutterActivity() {
private var isQuickTile: Boolean? = false
private val CHANNEL = "vikunja"
override fun onCreate(savedInstanceState: Bundle?) {
Log.e("TAG","test");
super.onCreate(savedInstanceState);
}
override fun onNewIntent(intent: Intent) {
handleIntent(intent, flutterEngine!!, true);
super.onResume()
}
private fun handleIntent(intent: Intent, flutterEngine: FlutterEngine, isNewIntent: Boolean) {
val action: String? = intent.action
val type: String? = intent.type
Log.e("VIKUNJA", "Action: $action")
Log.e("VIKUNJA", "Type: $type")
val channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
if ("ACTION_INSERT" == action && type != null && "ADD_NEW_TASK" == type) {
Log.e("VIKUNJA","Is ACTION_INSERT");
if(isNewIntent)
channel.invokeMethod("open_add_task", "")
isQuickTile = true;
}
else {
isQuickTile = false;
}
}
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
handleIntent(intent, flutterEngine, false)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
.setMethodCallHandler {
call, result ->
if (call.method!!.contentEquals("isQuickTile")) {
result.success(isQuickTile)
}
}
}
fun handleSendText(intent: Intent) {
//sharedText = intent.getStringExtra(Intent.EXTRA_TEXT)
}
}

View File

@ -0,0 +1,49 @@
package io.vikunja.flutteringvikunja
import android.content.Intent
import android.os.Build
import android.service.quicksettings.TileService
import android.util.Log
import androidx.annotation.RequiresApi
@RequiresApi(Build.VERSION_CODES.N)
class VikunjaTileService : TileService(){
override fun onClick() {
super.onClick()
Log.e("VIKUNJA","Clicked")
val addIntent = Intent(this,MainActivity::class.java)
addIntent.action = "ACTION_INSERT"
addIntent.type = "ADD_NEW_TASK"
addIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivityAndCollapse(addIntent)
// Called when the user click the tile
}
override fun onTileRemoved() {
super.onTileRemoved()
// Do something when the user removes the Tile
}
override fun onTileAdded() {
super.onTileAdded()
// Do something when the user add the Tile
}
override fun onStartListening() {
super.onStartListening()
// Called when the Tile becomes visible
}
override fun onStopListening() {
super.onStopListening()
// Called when the tile is no longer visible
}
}

View File

@ -15,6 +15,7 @@ class VikunjaApp extends StatelessWidget {
const VikunjaApp({Key key, this.home}) : super(key: key);
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Vikunja',
theme: buildVikunjaTheme(),

View File

@ -12,7 +12,6 @@ import 'package:vikunja_app/pages/landing_page.dart';
import 'package:vikunja_app/global.dart';
import 'package:vikunja_app/models/namespace.dart';
import 'package:vikunja_app/pages/settings.dart';
import 'package:vikunja_app/pages/placeholder.dart';
class HomePage extends StatefulWidget {

View File

@ -1,4 +1,6 @@
import 'package:after_layout/after_layout.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:vikunja_app/global.dart';
import 'dart:developer';
@ -18,12 +20,14 @@ class LandingPage extends StatefulWidget {
}
class LandingPageState extends State<LandingPage> {
class LandingPageState extends State<LandingPage> with AfterLayoutMixin<LandingPage> {
int defaultList;
List<Task> _list;
static const platform = const MethodChannel('vikunja');
void _updateDefaultList() {
VikunjaGlobal.of(context)
Future<void> _updateDefaultList() async {
return VikunjaGlobal.of(context)
.listService
.getDefaultList()
.then((value) => setState(() => defaultList = value == null ? null : int.tryParse(value)));
@ -31,11 +35,38 @@ class LandingPageState extends State<LandingPage> {
@override
void initState() {
Future.delayed(Duration.zero, () => _updateDefaultList());
Future.delayed(Duration.zero, () =>
_updateDefaultList().then((value) {
try {
platform.invokeMethod("isQuickTile","").then((value) => {
if(value is bool && value)
_addItemDialog(context)
});
} catch (e) {
log(e.toString());
}}));
super.initState();
}
@override
void afterFirstLayout(BuildContext context) {
try {
// This is needed when app is already open and quicktile is clicked
platform.setMethodCallHandler((call) {
switch (call.method) {
case "open_add_task":
_addItemDialog(context);
break;
}
return Future.value();
});
} catch (e) {
log(e.toString());
}
}
@override
Widget build(BuildContext context) {
if(_list == null)
@ -53,30 +84,28 @@ class LandingPageState extends State<LandingPage> {
: new Center(child: CircularProgressIndicator()),
floatingActionButton: Builder(
builder: (context) =>
defaultList == null ?
FloatingActionButton(
backgroundColor: Colors.grey,
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Please select a default list in the settings'),
));},
child: const Icon(Icons.add))
:
FloatingActionButton(
onPressed: () {
_addItemDialog(context);
},
child: const Icon(Icons.add),
),
)
));
}
_addItemDialog(BuildContext context) {
showDialog(
context: context,
builder: (_) => AddDialog(
onAddTask: (task) => _addTask(task, context),
decoration: new InputDecoration(
labelText: 'Task Name', hintText: 'eg. Milk')));
if(defaultList == null) {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Please select a default list in the settings'),
));
} else {
showDialog(
context: context,
builder: (_) =>
AddDialog(
onAddTask: (task) => _addTask(task, context),
decoration: new InputDecoration(
labelText: 'Task Name', hintText: 'eg. Milk')));
}
}
_addTask(Task task, BuildContext context) {

View File

@ -196,7 +196,7 @@ class MockedTaskService implements TaskService {
class MockedUserService implements UserService {
@override
Future<UserTokenPair> login(String username, password) {
Future<UserTokenPair> login(String username, password, {bool rememberMe = false}) {
return Future.value(UserTokenPair(_users[1], 'abcdefg'));
}
@ -209,4 +209,6 @@ class MockedUserService implements UserService {
Future<User> getCurrentUser() {
return Future.value(_users[1]);
}
}