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:
parent
74069180fa
commit
7bc2157834
|
@ -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>
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user