implementing foreground service
This commit is contained in:
parent
12d1d9ba3d
commit
dbd08f2eb3
66 changed files with 1391 additions and 2489 deletions
51
app/ForegroundService.js
Normal file
51
app/ForegroundService.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
var ForegroundService = /** @class */ (function(_super) {
|
||||
__extends(ForegroundService, _super)
|
||||
function ForegroundService() {
|
||||
return (_super !== null && _super.apply(this, arguments)) || this
|
||||
}
|
||||
ForegroundService.prototype.onStartCommand = function(
|
||||
intent,
|
||||
flags,
|
||||
startId
|
||||
) {
|
||||
console.log('onStartCommand')
|
||||
_super.prototype.onStartCommand.call(this, intent, flags, startId)
|
||||
return android.app.Service.START_STICKY
|
||||
}
|
||||
ForegroundService.prototype.onCreate = function() {
|
||||
console.log('onCreate')
|
||||
_super.prototype.onCreate.call(this)
|
||||
this.startForeground(1, this.getNotification())
|
||||
}
|
||||
ForegroundService.prototype.onBind = function(intent) {
|
||||
return _super.prototype.onBind.call(this, intent)
|
||||
}
|
||||
ForegroundService.prototype.onUnbind = function(intent) {
|
||||
return _super.prototype.onUnbind.call(this, intent)
|
||||
}
|
||||
ForegroundService.prototype.onDestroy = function() {
|
||||
console.log('onDestroy')
|
||||
this.stopForeground(true)
|
||||
}
|
||||
ForegroundService.prototype.getNotification = function() {
|
||||
var channel = new android.app.NotificationChannel(
|
||||
'channel_01',
|
||||
'ForegroundService Channel',
|
||||
android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
var notificationManager = this.getSystemService(
|
||||
android.content.Context.NOTIFICATION_SERVICE
|
||||
)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
var builder = new android.app.Notification.Builder(
|
||||
this.getApplicationContext(),
|
||||
'channel_01'
|
||||
)
|
||||
return builder.build()
|
||||
}
|
||||
ForegroundService = __decorate(
|
||||
[JavaProxy('com.tns.ForegroundService')],
|
||||
ForegroundService
|
||||
)
|
||||
return ForegroundService
|
||||
})(android.app.Service)
|
|
@ -16,7 +16,7 @@
|
|||
@tap="$navigateTo(CTSettings)"
|
||||
/>
|
||||
</GridLayout>
|
||||
<SingleTimer
|
||||
<Timer
|
||||
v-for="(timer, i) in activeTimers"
|
||||
:key="timer.id"
|
||||
ref="singleTimer"
|
||||
|
@ -41,22 +41,19 @@
|
|||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
<Button class="ico fab" :text="icon.plus" @tap="addTimer" col="2" />
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
row="1"
|
||||
class="appbar snackBar"
|
||||
:hidden="!showUndo"
|
||||
columns="auto, *, auto"
|
||||
@swipe="hideUndoBar"
|
||||
>
|
||||
<Button :text="countdown" class="ico countdown tb" />
|
||||
<Label class="title" col="1" :text="snackMsg | L" />
|
||||
<Button class="ico fab" :text="icon.undo" @tap="undoDel" col="3" />
|
||||
</GridLayout>
|
||||
<SnackBar
|
||||
:hidden="!showUndo || toast"
|
||||
:count="countdown"
|
||||
:msg="snackMsg"
|
||||
:undo="undoDel"
|
||||
:action="hideBar"
|
||||
/>
|
||||
<Toast :toast="toast" :action="hideBar" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
import { localize } from "@nativescript/localize";
|
||||
import {
|
||||
Observable,
|
||||
|
@ -64,20 +61,25 @@ import {
|
|||
Application,
|
||||
ApplicationSettings,
|
||||
AndroidApplication,
|
||||
Utils,
|
||||
} from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import CTSettings from "./Settings/CTSettings.vue";
|
||||
import ActionDialog from "./modal/ActionDialog.vue";
|
||||
import CookingTimePicker from "./modal/CookingTimePicker.vue";
|
||||
import CookingTimer from "./CookingTimer.vue";
|
||||
import SingleTimer from "./SingleTimer.vue";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
import Action from "./modals/Action.vue";
|
||||
import CookingTimer from "./CookingTimer.vue";
|
||||
import CTSettings from "./settings/CTSettings.vue";
|
||||
import TimePickerHMS from "./modals/TimePickerHMS.vue";
|
||||
import Timer from "./sub/Timer.vue";
|
||||
import Toast from "./sub/Toast.vue";
|
||||
import SnackBar from "./sub/SnackBar.vue";
|
||||
|
||||
import * as utils from "~/shared/utils";
|
||||
// import { fgs } from "~/foreground.android";
|
||||
import { EventBus } from "~/main";
|
||||
let undoTimer;
|
||||
|
||||
export default {
|
||||
components: { SingleTimer },
|
||||
components: { Timer, Toast, SnackBar },
|
||||
props: ["recipeID"],
|
||||
data() {
|
||||
return {
|
||||
|
@ -88,6 +90,7 @@ export default {
|
|||
showUndo: false,
|
||||
undo: false,
|
||||
CTSettings: CTSettings,
|
||||
toast: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -111,9 +114,8 @@ export default {
|
|||
"addTimerPreset",
|
||||
"updateActiveTimer",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.setComponent("CookingTimer");
|
||||
},
|
||||
onAppBarLoad({ object }) {
|
||||
|
@ -170,17 +172,17 @@ export default {
|
|||
let pausedCount = this.activeTimers.filter((e) => e.isPaused).length;
|
||||
let ongoingCount = activeCount - pausedCount;
|
||||
console.log("notifying");
|
||||
utils.TimerNotification.show({
|
||||
utils.TimerNotif.show({
|
||||
bID: "bringToFront",
|
||||
cID: "CookingTimer",
|
||||
cName: "Cooking Timer",
|
||||
cID: "cti",
|
||||
cName: "Cooking Timer info",
|
||||
description: `${ongoingCount} ongoing, ${pausedCount} paused`,
|
||||
nID: 999,
|
||||
priority: 0,
|
||||
priority: -2,
|
||||
sound: null,
|
||||
title: localize("timer"),
|
||||
});
|
||||
if (activeCount <= 0) utils.TimerNotification.clear(999);
|
||||
if (activeCount <= 0) utils.TimerNotif.clear(999);
|
||||
},
|
||||
intentListener({ intent, android }) {
|
||||
let ct = "CookingTimer";
|
||||
|
@ -191,10 +193,11 @@ export default {
|
|||
let openTimer = setInterval(() => {
|
||||
if (comp == ct) clearInterval(openTimer);
|
||||
else {
|
||||
this.$navigateTo(CookingTimer);
|
||||
if (comp == "CTSettings") this.$navigateBack();
|
||||
else this.$navigateTo(CookingTimer);
|
||||
comp = ct;
|
||||
}
|
||||
// Application.off(Application.launchEvent, this.intentListener);
|
||||
Application.off(Application.launchEvent, this.intentListener);
|
||||
Application.android.off(
|
||||
AndroidApplication.activityNewIntentEvent,
|
||||
this.intentListener
|
||||
|
@ -210,11 +213,11 @@ export default {
|
|||
let title = timer.label;
|
||||
let time = this.formattedTime(timer.time);
|
||||
let bID = "timer" + timer.id;
|
||||
utils.TimerNotification.show({
|
||||
utils.TimerNotif.show({
|
||||
actions: true,
|
||||
bID,
|
||||
cID: "FiringTimers",
|
||||
cName: "Firing timers",
|
||||
cID: "cta",
|
||||
cName: "Cooking Timer alerts",
|
||||
description: time,
|
||||
nID: timer.id,
|
||||
priority: 1,
|
||||
|
@ -228,10 +231,18 @@ export default {
|
|||
EventBus.$emit(bID, action);
|
||||
});
|
||||
},
|
||||
startForegroundService() {
|
||||
const ctx = Utils.ad.getApplicationContext();
|
||||
const intent = new android.content.Intent();
|
||||
intent.setClassName(ctx, "com.tns.ForegroundService");
|
||||
ctx.startService(intent);
|
||||
},
|
||||
|
||||
// DATA HANDLERS
|
||||
addTimer() {
|
||||
this.$showModal(CookingTimePicker, {
|
||||
// fgs.class
|
||||
this.startForegroundService();
|
||||
this.$showModal(TimePickerHMS, {
|
||||
props: {
|
||||
title: "ntmr",
|
||||
label: `${localize("tmr", this.activeTimers.length + 1)}`,
|
||||
|
@ -244,7 +255,7 @@ export default {
|
|||
let list = this.timerPresets.map(
|
||||
(e) => `${e.label} - ${this.formattedTime(e.time)}`
|
||||
);
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "tmrPrsts",
|
||||
list,
|
||||
|
@ -285,7 +296,7 @@ export default {
|
|||
removeTimer(id, index, noUndo) {
|
||||
let temp = this.activeTimers[index];
|
||||
this.removeActiveTimer(index);
|
||||
utils.TimerNotification.clear(id);
|
||||
utils.TimerNotif.clear(id);
|
||||
if (!noUndo) {
|
||||
this.showUndoBar("tmrClr")
|
||||
.then(() => {
|
||||
|
@ -306,6 +317,7 @@ export default {
|
|||
timer.recipeID = timer.timerInterval = null;
|
||||
timer.preset = 1;
|
||||
this.addTimerPreset(timer);
|
||||
this.showToast("aTPrst");
|
||||
},
|
||||
togglePause(timer, bool) {
|
||||
if (typeof bool === "boolean") timer.isPaused = bool;
|
||||
|
@ -313,6 +325,12 @@ export default {
|
|||
this.updateActiveTimer(timer);
|
||||
this.notifyTimers();
|
||||
},
|
||||
showToast(data) {
|
||||
this.toast = localize(data);
|
||||
utils.timer(5, (val) => {
|
||||
if (!val) this.toast = val;
|
||||
});
|
||||
},
|
||||
showUndoBar(message) {
|
||||
return new Promise((resolve, reject) => {
|
||||
clearTimeout(undoTimer);
|
||||
|
@ -335,7 +353,8 @@ export default {
|
|||
}, 100);
|
||||
});
|
||||
},
|
||||
hideUndoBar({ object }) {
|
||||
hideBar({ object }) {
|
||||
this.appbar.translateY = 64;
|
||||
object
|
||||
.animate({
|
||||
opacity: 0,
|
||||
|
@ -345,7 +364,7 @@ export default {
|
|||
})
|
||||
.then(() => {
|
||||
this.showUndo = false;
|
||||
this.appbar.translateY = 64;
|
||||
this.toast = null;
|
||||
this.appbar.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
duration: 250,
|
||||
|
@ -366,7 +385,7 @@ export default {
|
|||
},
|
||||
},
|
||||
created() {
|
||||
// Application.on(Application.launchEvent, this.intentListener);
|
||||
Application.on(Application.launchEvent, this.intentListener);
|
||||
Application.android.on(
|
||||
AndroidApplication.activityNewIntentEvent,
|
||||
this.intentListener
|
||||
|
|
|
@ -267,7 +267,15 @@
|
|||
/>
|
||||
<ActivityIndicator col="2" v-if="saving" :busy="saving" />
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
<SnackBar
|
||||
:hidden="!showUndo"
|
||||
colSpan="2"
|
||||
:count="countdown"
|
||||
:msg="snackMsg"
|
||||
:undo="undoDel"
|
||||
:action="hideUndoBar"
|
||||
/>
|
||||
<!-- <GridLayout
|
||||
row="1"
|
||||
class="appbar snackBar"
|
||||
:hidden="!showUndo"
|
||||
|
@ -278,7 +286,7 @@
|
|||
<Button :text="countdown" class="ico countdown tb" />
|
||||
<Label class="title" col="1" :text="snackMsg | L" />
|
||||
<Button class="ico fab" :text="icon.undo" @tap="undoDel" col="3" />
|
||||
</GridLayout>
|
||||
</GridLayout> -->
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
@ -300,14 +308,18 @@ import {
|
|||
import { localize } from "@nativescript/localize";
|
||||
import { ImageCropper } from "nativescript-imagecropper";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import ActionDialog from "./modal/ActionDialog.vue";
|
||||
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
||||
import PromptDialog from "./modal/PromptDialog.vue";
|
||||
import TimePicker from "./modal/TimePicker.vue";
|
||||
import Action from "./modals/Action";
|
||||
import ActionWithSearch from "./modals/ActionWithSearch";
|
||||
import Confirm from "./modals/Confirm";
|
||||
import Prompt from "./modals/Prompt";
|
||||
import TimePickerHM from "./modals/TimePickerHM";
|
||||
import * as utils from "~/shared/utils";
|
||||
import SnackBar from "./sub/SnackBar";
|
||||
let undoTimer;
|
||||
export default {
|
||||
components: {
|
||||
SnackBar,
|
||||
},
|
||||
props: [
|
||||
"recipeID",
|
||||
"filterFavourites",
|
||||
|
@ -384,9 +396,8 @@ export default {
|
|||
"addListItemAction",
|
||||
"unSyncCombinationsAction",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.hijackBackEvent();
|
||||
},
|
||||
onPageUnload() {
|
||||
|
@ -424,7 +435,7 @@ export default {
|
|||
this.clearEmptyFields(true);
|
||||
if (this.recipe.image) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "recPic",
|
||||
list: ["aap", "rp"],
|
||||
|
@ -488,7 +499,7 @@ export default {
|
|||
// DATA LIST
|
||||
showCuisine(focus) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "cui",
|
||||
list: this.cuisines,
|
||||
|
@ -496,7 +507,7 @@ export default {
|
|||
},
|
||||
}).then((action) => {
|
||||
if (action == "aNBtn") {
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal(Prompt, {
|
||||
props: {
|
||||
title: "newCui",
|
||||
action: "aBtn",
|
||||
|
@ -526,7 +537,7 @@ export default {
|
|||
},
|
||||
showCategories(focus) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "cat",
|
||||
list: this.categories,
|
||||
|
@ -534,7 +545,7 @@ export default {
|
|||
},
|
||||
}).then((action) => {
|
||||
if (action == "aNBtn") {
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal(Prompt, {
|
||||
props: {
|
||||
title: "nwCat",
|
||||
action: "aBtn",
|
||||
|
@ -564,7 +575,7 @@ export default {
|
|||
},
|
||||
showYieldUnits(focus) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "yieldU",
|
||||
list: this.yieldUnits,
|
||||
|
@ -572,7 +583,7 @@ export default {
|
|||
},
|
||||
}).then((action) => {
|
||||
if (action == "aNBtn") {
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal(Prompt, {
|
||||
props: {
|
||||
title: "nwYiU",
|
||||
action: "aBtn",
|
||||
|
@ -602,7 +613,7 @@ export default {
|
|||
},
|
||||
showDifficultyLevel(focus) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "Difficulty level",
|
||||
list: this.difficultyLevels,
|
||||
|
@ -620,7 +631,7 @@ export default {
|
|||
},
|
||||
showUnits(e, focus, index) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "Unit",
|
||||
list: this.units,
|
||||
|
@ -628,7 +639,7 @@ export default {
|
|||
},
|
||||
}).then((action) => {
|
||||
if (action == "aNBtn") {
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal(Prompt, {
|
||||
props: {
|
||||
title: "newUnit",
|
||||
action: "aBtn",
|
||||
|
@ -662,7 +673,7 @@ export default {
|
|||
let filteredRecipes = this.recipes.filter(
|
||||
(e) => !existingCombinations.includes(e.id)
|
||||
);
|
||||
this.$showModal(ActionDialogWithSearch, {
|
||||
this.$showModal(ActionWithSearch, {
|
||||
props: {
|
||||
title: "selRec",
|
||||
recipes: filteredRecipes,
|
||||
|
@ -923,7 +934,7 @@ export default {
|
|||
let t = this.recipe[time].split(":");
|
||||
let hr = t[0];
|
||||
let min = t[1];
|
||||
this.$showModal(TimePicker, {
|
||||
this.$showModal(TimePickerHM, {
|
||||
props: {
|
||||
title: `${time == "prepTime" ? "prepT" : "cookT"}`,
|
||||
action: "SET",
|
||||
|
@ -975,7 +986,7 @@ export default {
|
|||
navigateBack() {
|
||||
if (this.hasChanges) {
|
||||
this.modalOpen = true;
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "unsaved",
|
||||
description: localize("disc"),
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
col="1"
|
||||
class="ico"
|
||||
:text="icon.cog"
|
||||
@tap="navigateTo(Settings, 'Settings', true)"
|
||||
@tap="navigateTo(AppSettings, 'Settings', true)"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
|
@ -432,10 +432,10 @@ import EditRecipe from "./EditRecipe";
|
|||
import MealPlanner from "./MealPlanner";
|
||||
import CookingTimer from "./CookingTimer";
|
||||
import GroceryList from "./GroceryList";
|
||||
import Settings from "./Settings";
|
||||
import ActionDialog from "./modal/ActionDialog.vue";
|
||||
import ConfirmDialog from "./modal/ConfirmDialog.vue";
|
||||
import Filters from "./modal/Filters.vue";
|
||||
import AppSettings from "./settings/AppSettings";
|
||||
import Action from "./modals/Action";
|
||||
import Confirm from "./modals/Confirm";
|
||||
import Filters from "./modals/Filter";
|
||||
import * as utils from "~/shared/utils";
|
||||
let lastTime = 0;
|
||||
let lastShake = 0;
|
||||
|
@ -456,7 +456,7 @@ export default {
|
|||
scrollPos: 1,
|
||||
filterFavourites: false,
|
||||
filterTrylater: false,
|
||||
Settings: Settings,
|
||||
AppSettings: AppSettings,
|
||||
MealPlanner: MealPlanner,
|
||||
CookingTimer: CookingTimer,
|
||||
GroceryList: GroceryList,
|
||||
|
@ -603,9 +603,8 @@ export default {
|
|||
: View.SYSTEM_UI_FLAG_DARK_STATUS_BAR
|
||||
);
|
||||
},
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.filterFavourites
|
||||
? this.setComponent("favourites")
|
||||
: this.filterTrylater
|
||||
|
@ -685,7 +684,7 @@ export default {
|
|||
openSort() {
|
||||
this.showTools = false;
|
||||
this.releaseBackEvent();
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "srt",
|
||||
list: [
|
||||
|
@ -748,7 +747,7 @@ export default {
|
|||
this.recipes.findIndex((e) => e.id === this.selection[0])
|
||||
].title
|
||||
}"`;
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: localize("conf"),
|
||||
description: `${localize(
|
||||
|
@ -1080,7 +1079,12 @@ export default {
|
|||
if (!this.recipes.length) this.initRecipes();
|
||||
this.initMealPlans();
|
||||
this.initListItems();
|
||||
if (!this.timerSound.title) this.setTimerSound(utils.getTones()[0]);
|
||||
if (!this.timerSound.title) {
|
||||
let hasTimerSound = ApplicationSettings.getString("timerSound", 0);
|
||||
this.setTimerSound(
|
||||
hasTimerSound ? JSON.parse(hasTimerSound) : utils.getTones().defaultTone
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -28,9 +28,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(["setComponent"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.setComponent("GroceryList");
|
||||
},
|
||||
// HELPERS
|
||||
|
|
|
@ -120,17 +120,13 @@
|
|||
col="3"
|
||||
/>
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
row="1"
|
||||
class="appbar snackBar"
|
||||
<SnackBar
|
||||
:hidden="!showUndo"
|
||||
columns="auto, *, auto"
|
||||
@swipe="hideUndoBar"
|
||||
>
|
||||
<Button :text="countdown" class="ico countdown tb" />
|
||||
<Label class="title" col="1" :text="snackMsg | L" />
|
||||
<Button class="ico fab" :text="icon.undo" @tap="undoDel" col="3" />
|
||||
</GridLayout>
|
||||
:count="countdown"
|
||||
:msg="snackMsg"
|
||||
:undo="undoDel"
|
||||
:action="hideUndoBar"
|
||||
/>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
@ -138,12 +134,16 @@
|
|||
<script>
|
||||
import { Observable, CoreTypes } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import ViewRecipe from "./ViewRecipe.vue";
|
||||
import MPSettings from "./Settings/MPSettings.vue";
|
||||
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
|
||||
import ViewRecipe from "./ViewRecipe";
|
||||
import MPSettings from "./settings/MPSettings";
|
||||
import ActionWithSearch from "./modals/ActionWithSearch";
|
||||
import SnackBar from "./sub/SnackBar";
|
||||
let undoTimer;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SnackBar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mealTimes: ["breakfast", "lunch", "dinner", "snacks"],
|
||||
|
@ -227,9 +227,8 @@ export default {
|
|||
"addMealPlanAction",
|
||||
"deleteMealPlanAction",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.setComponent("MealPlanner");
|
||||
if (!this.today || this.today === new Date().getDate()) this.goToToday();
|
||||
},
|
||||
|
@ -342,7 +341,7 @@ export default {
|
|||
let filteredRecipes = this.recipes.filter((e) =>
|
||||
this.getRecipes[type] ? !this.getRecipes[type].includes(e.id) : true
|
||||
);
|
||||
this.$showModal(ActionDialogWithSearch, {
|
||||
this.$showModal(ActionWithSearch, {
|
||||
props: {
|
||||
title: "selRec",
|
||||
recipes: filteredRecipes,
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'Settings' | L" />
|
||||
</v-template>
|
||||
<v-template if="$index == 6">
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.view)"
|
||||
>
|
||||
<Label
|
||||
verticalAlignment="center"
|
||||
class="ico"
|
||||
:text="icon[item.icon]"
|
||||
/>
|
||||
<Label verticalAlignment="center" col="1" :text="item.title | L" />
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import Interface from "./Settings/Interface.vue";
|
||||
import Options from "./Settings/Options.vue";
|
||||
import Database from "./Settings/Database.vue";
|
||||
import Reset from "./Settings/Reset.vue";
|
||||
import About from "./Settings/About.vue";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{},
|
||||
{
|
||||
icon: "interface",
|
||||
title: "intf",
|
||||
view: Interface,
|
||||
},
|
||||
{
|
||||
icon: "opts",
|
||||
title: "opts",
|
||||
view: Options,
|
||||
},
|
||||
{
|
||||
icon: "db",
|
||||
title: "db",
|
||||
view: Database,
|
||||
},
|
||||
{
|
||||
icon: "reset",
|
||||
title: "rest",
|
||||
view: Reset,
|
||||
},
|
||||
{
|
||||
icon: "info",
|
||||
title: "About",
|
||||
view: About,
|
||||
},
|
||||
{},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setComponent"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
this.setComponent("Settings");
|
||||
},
|
||||
// HELPERS
|
||||
navigateTo(view) {
|
||||
this.$navigateTo(view, {
|
||||
transition: {
|
||||
name: "slide",
|
||||
duration: 200,
|
||||
curve: "easeOut",
|
||||
},
|
||||
});
|
||||
},
|
||||
touch({ object, action }, view) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") this.navigateTo(view);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,139 +0,0 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'Settings' | L" />
|
||||
</v-template>
|
||||
<v-template if="item.type == 'switch'">
|
||||
<GridLayout columns="auto, *, auto" class="option">
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1" verticalAlignment="center">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label
|
||||
v-if="item.subTitle"
|
||||
:text="item.subTitle | L"
|
||||
class="sub"
|
||||
/>
|
||||
</StackLayout>
|
||||
<Switch
|
||||
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
||||
col="2"
|
||||
:checked="item.checked"
|
||||
@checkedChange="item.action"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template if="item.type == 'list'">
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.action)"
|
||||
>
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label :text="item.subTitle" class="sub" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable, Device } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import ActionDialog from "../modal/ActionDialog.vue";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(["icon", "timerDelay", "timerSound", "timerVibrate"]),
|
||||
items() {
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "list",
|
||||
icon: "delay",
|
||||
title: "dlyDur",
|
||||
subTitle: this.timerDelay,
|
||||
action: this.showDelayList,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "sound",
|
||||
title: "tmrSnd",
|
||||
subTitle: this.timerSound.title,
|
||||
action: this.showSoundsList,
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "vibrate",
|
||||
title: "tmrvbrt",
|
||||
checked: this.timerVibrate,
|
||||
action: this.toggleTimerVibrate,
|
||||
},
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setTimerDelay", "setTimerSound", "setTimerVibrate"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
},
|
||||
toggleTimerVibrate({ object }) {
|
||||
this.setTimerVibrate(object.checked);
|
||||
},
|
||||
showDelayList() {
|
||||
let list = [
|
||||
...Array.from(Array(4), (_, x) => x + 1),
|
||||
...Array.from(Array(6), (_, x) => (x + 1) * 5),
|
||||
].map(
|
||||
(e, i) => `${e} ${i == 0 ? localize("minute") : localize("minutes")}`
|
||||
);
|
||||
this.$showModal(ActionDialog, {
|
||||
props: {
|
||||
title: "dlyDur",
|
||||
list,
|
||||
},
|
||||
}).then((dur) => dur && this.setTimerDelay(dur));
|
||||
},
|
||||
showSoundsList() {
|
||||
let tones = utils.getTones();
|
||||
this.$showModal(ActionDialog, {
|
||||
props: {
|
||||
title: "tmrSnd",
|
||||
list: tones.map((e) => e.title),
|
||||
},
|
||||
}).then(
|
||||
(tone) =>
|
||||
tone &&
|
||||
tone !== this.timerSound.title &&
|
||||
this.setTimerSound(tones.filter((e) => e.title === tone)[0])
|
||||
);
|
||||
},
|
||||
|
||||
// HELPERS
|
||||
touch({ object, action }, method) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") method();
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,75 +0,0 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'Settings' | L" />
|
||||
</v-template>
|
||||
<v-template if="item.type == 'switch'">
|
||||
<GridLayout columns="auto, *, auto" class="option">
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1" verticalAlignment="center">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label
|
||||
v-if="item.subTitle"
|
||||
:text="item.subTitle | L"
|
||||
class="sub"
|
||||
/>
|
||||
</StackLayout>
|
||||
<Switch
|
||||
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
||||
col="2"
|
||||
:checked="item.checked"
|
||||
@checkedChange="item.action"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapState(["icon", "mondayFirst"]),
|
||||
items() {
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "week",
|
||||
title: "swm",
|
||||
checked: this.mondayFirst,
|
||||
action: this.toggleFirstDay,
|
||||
},
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setFirstDay"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
},
|
||||
toggleFirstDay({ object }) {
|
||||
this.setFirstDay(object.checked);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,109 +0,0 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'opts' | L" />
|
||||
</v-template>
|
||||
<v-template if="item.type == 'switch'">
|
||||
<GridLayout columns="auto, *, auto" class="option">
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1" verticalAlignment="center">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label
|
||||
v-if="item.subTitle"
|
||||
:text="item.subTitle | L"
|
||||
class="sub"
|
||||
/>
|
||||
</StackLayout>
|
||||
<Switch
|
||||
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
||||
col="2"
|
||||
:checked="item.checked"
|
||||
@checkedChange="item.action"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<GridLayout
|
||||
v-show="!toast"
|
||||
row="1"
|
||||
class="appbar"
|
||||
rows="*"
|
||||
columns="auto, *"
|
||||
>
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
v-show="toast"
|
||||
row="1"
|
||||
colSpan="2"
|
||||
class="appbar snackBar"
|
||||
columns="*"
|
||||
@tap="toast = null"
|
||||
>
|
||||
<FlexboxLayout minHeight="48" alignItems="center">
|
||||
<Label class="title msg" :text="toast" />
|
||||
</FlexboxLayout>
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
toast: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "shakeEnabled"]),
|
||||
items() {
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "shuf",
|
||||
title: "sVw",
|
||||
subTitle: "sVwInfo",
|
||||
checked: this.shakeEnabled,
|
||||
action: this.toggleShake,
|
||||
},
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setShake"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
},
|
||||
// SHAKE VIEW RANDOM RECIPE
|
||||
toggleShake({ object }) {
|
||||
let checked = object.checked;
|
||||
if (checked && !utils.hasAccelerometer()) {
|
||||
object.checked = false;
|
||||
this.toast = localize("noAccSensor");
|
||||
utils.timer(5, (val) => {
|
||||
if (!val) this.toast = val;
|
||||
});
|
||||
} else this.setShake(checked);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -232,17 +232,7 @@
|
|||
@tap="shareHandler"
|
||||
/>
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
v-show="toast"
|
||||
row="1"
|
||||
class="appbar snackBar"
|
||||
columns="*"
|
||||
@swipe="hideLastTried"
|
||||
>
|
||||
<FlexboxLayout minHeight="48" alignItems="center">
|
||||
<Label class="title msg" :text="toast" />
|
||||
</FlexboxLayout>
|
||||
</GridLayout>
|
||||
<Toast :toast="toast" :action="hideLastTried" />
|
||||
<AbsoluteLayout rowSpan="2">
|
||||
<Image
|
||||
@tap="({ object }) => (object.cancel = true)"
|
||||
|
@ -269,17 +259,18 @@ import {
|
|||
Observable,
|
||||
Screen,
|
||||
CoreTypes,
|
||||
Color,
|
||||
} from "@nativescript/core";
|
||||
import { localize } from "@nativescript/localize";
|
||||
const intl = require("nativescript-intl");
|
||||
import { mapActions, mapState } from "vuex";
|
||||
import CookingTimer from "./CookingTimer.vue";
|
||||
import EditRecipe from "./EditRecipe.vue";
|
||||
import ActionDialog from "./modal/ActionDialog.vue";
|
||||
import PromptDialog from "./modal/PromptDialog.vue";
|
||||
import Action from "./modals/Action.vue";
|
||||
import Toast from "./sub/Toast.vue";
|
||||
import Prompt from "./modals/Prompt.vue";
|
||||
import * as utils from "~/shared/utils";
|
||||
export default {
|
||||
components: { Toast },
|
||||
props: ["filterTrylater", "recipeID"],
|
||||
data() {
|
||||
return {
|
||||
|
@ -337,9 +328,8 @@ export default {
|
|||
"setRatingAction",
|
||||
"toggleCartAction",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.busy = this.photoOpen = false;
|
||||
this.setComponent("ViewRecipe");
|
||||
if (this.yieldMultiplier == this.recipe.yieldQuantity)
|
||||
|
@ -462,7 +452,7 @@ export default {
|
|||
return localize(title) + text;
|
||||
},
|
||||
changeYield() {
|
||||
this.$showModal(PromptDialog, {
|
||||
this.$showModal(Prompt, {
|
||||
props: {
|
||||
title: `${localize("req", localize(this.recipe.yieldUnit))}`,
|
||||
placeholder: Math.abs(parseFloat(this.yieldMultiplier)),
|
||||
|
@ -694,7 +684,7 @@ export default {
|
|||
// SHARE ACTION
|
||||
shareHandler() {
|
||||
if (this.recipe.image) {
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "shr",
|
||||
list: ["rec", "pht"],
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
import { Screen } from "@nativescript/core";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import ConfirmDialog from "./ConfirmDialog.vue";
|
||||
import Confirm from "./Confirm.vue";
|
||||
|
||||
interface IData {
|
||||
newList: unknown[];
|
||||
|
@ -92,7 +92,7 @@ export default {
|
|||
this.$modal.close(item);
|
||||
},
|
||||
deletionConfirmation(description: string): void {
|
||||
return this.$showModal(ConfirmDialog, {
|
||||
return this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "conf",
|
||||
description,
|
|
@ -12,11 +12,7 @@
|
|||
</v-template>
|
||||
<v-template if="$index == 1">
|
||||
<StackLayout class="app-info">
|
||||
<Image
|
||||
class="icon"
|
||||
src="res://logo"
|
||||
stretch="none"
|
||||
/>
|
||||
<Image class="icon" src="res://logo" stretch="none" />
|
||||
<Label class="name tb tac" :text="'EnRecipes' | L" />
|
||||
<Label :text="getVersion" class="version tb tac" />
|
||||
|
||||
|
@ -99,9 +95,8 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
},
|
||||
// HELPERS
|
||||
openURL(url) {
|
82
app/components/settings/AppSettings.vue
Normal file
82
app/components/settings/AppSettings.vue
Normal file
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<OptionsList title="Settings" :items="items" :action="navigateTo" />
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import Interface from "./Interface.vue";
|
||||
import Options from "./Options.vue";
|
||||
import Database from "./Database.vue";
|
||||
import Reset from "./Reset.vue";
|
||||
import About from "./About.vue";
|
||||
import OptionsList from "../sub/OptionsList.vue";
|
||||
export default {
|
||||
components: { OptionsList },
|
||||
data() {
|
||||
return {
|
||||
items: [
|
||||
{},
|
||||
{
|
||||
type: "list",
|
||||
icon: "interface",
|
||||
title: "intf",
|
||||
data: Interface,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "opts",
|
||||
title: "opts",
|
||||
data: Options,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "db",
|
||||
title: "db",
|
||||
data: Database,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "reset",
|
||||
title: "rest",
|
||||
data: Reset,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "info",
|
||||
title: "About",
|
||||
data: About,
|
||||
},
|
||||
{},
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setComponent"]),
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.setComponent("Settings");
|
||||
},
|
||||
// HELPERS
|
||||
navigateTo(view) {
|
||||
this.$navigateTo(view, {
|
||||
transition: {
|
||||
name: "slide",
|
||||
duration: 200,
|
||||
curve: "easeOut",
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
134
app/components/settings/CTSettings.vue
Normal file
134
app/components/settings/CTSettings.vue
Normal file
|
@ -0,0 +1,134 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<OptionsList title="Settings" :items="items" />
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable, Device, Application, Utils } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
import Action from "../modals/Action";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
components: { OptionsList },
|
||||
computed: {
|
||||
...mapState(["icon", "timerDelay", "timerSound", "timerVibrate"]),
|
||||
items() {
|
||||
let options = [
|
||||
{
|
||||
type: "list",
|
||||
icon: "sound",
|
||||
title: "tmrSnd",
|
||||
subTitle: this.timerSound.title,
|
||||
action: this.showSoundsList,
|
||||
},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "vibrate",
|
||||
title: "tmrvbrt",
|
||||
checked: this.timerVibrate,
|
||||
action: this.toggleTimerVibrate,
|
||||
},
|
||||
];
|
||||
let openSettings = [
|
||||
{
|
||||
type: "list",
|
||||
icon: "sound",
|
||||
title: "notifSetg",
|
||||
subTitle: null,
|
||||
action: this.openNotificationChannelSettings,
|
||||
},
|
||||
];
|
||||
let list = this.channelExists() ? openSettings : options;
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "list",
|
||||
icon: "delay",
|
||||
title: "dlyDur",
|
||||
subTitle: this.timerDelay,
|
||||
action: this.showDelayList,
|
||||
},
|
||||
...list,
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions([
|
||||
"setTimerDelay",
|
||||
"setTimerSound",
|
||||
"setTimerVibrate",
|
||||
"setComponent",
|
||||
]),
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
this.setComponent("CTSettings");
|
||||
},
|
||||
showDelayList() {
|
||||
let list = [
|
||||
...Array.from(Array(4), (_, x) => x + 1),
|
||||
...Array.from(Array(6), (_, x) => (x + 1) * 5),
|
||||
].map(
|
||||
(e, i) => `${e} ${i == 0 ? localize("minute") : localize("minutes")}`
|
||||
);
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "dlyDur",
|
||||
list,
|
||||
},
|
||||
}).then((dur) => dur && this.setTimerDelay(dur));
|
||||
},
|
||||
showSoundsList() {
|
||||
let getTones = utils.getTones();
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "tmrSnd",
|
||||
list: getTones.tones.map((e) => e.title),
|
||||
},
|
||||
}).then(
|
||||
(tone) =>
|
||||
tone &&
|
||||
tone !== this.timerSound.title &&
|
||||
this.setTimerSound(getTones.tones.filter((e) => e.title === tone)[0])
|
||||
);
|
||||
},
|
||||
toggleTimerVibrate() {
|
||||
this.setTimerVibrate(!this.timerVibrate);
|
||||
},
|
||||
openNotificationChannelSettings() {
|
||||
const ctx = Application.android.context;
|
||||
const Settings = android.provider.Settings;
|
||||
const Intent = android.content.Intent;
|
||||
let intent = new Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
|
||||
intent.putExtra(
|
||||
Settings.EXTRA_APP_PACKAGE,
|
||||
Application.android.packageName
|
||||
);
|
||||
intent.putExtra(Settings.EXTRA_CHANNEL_ID, "cta");
|
||||
intent.setFlags(android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
ctx.startActivity(intent);
|
||||
},
|
||||
|
||||
// HELPERS
|
||||
channelExists() {
|
||||
if (Device.sdkVersion * 1 >= 26) {
|
||||
const ctx = Utils.ad.getApplicationContext();
|
||||
const NotifySrv = ctx.getSystemService(
|
||||
android.content.Context.NOTIFICATION_SERVICE
|
||||
);
|
||||
return NotifySrv.getNotificationChannel("cta");
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,32 +1,7 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'db' | L" />
|
||||
</v-template>
|
||||
<v-template if="$index == 4">
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.action)"
|
||||
>
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1" verticalAlignment="center">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label v-if="item.subTitle" :text="item.subTitle" class="sub" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<OptionsList title="db" :items="items" />
|
||||
<GridLayout
|
||||
v-show="!toast && !progress"
|
||||
row="1"
|
||||
|
@ -36,18 +11,7 @@
|
|||
>
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
v-show="toast"
|
||||
row="1"
|
||||
colSpan="2"
|
||||
class="appbar snackBar"
|
||||
columns="*"
|
||||
@tap="toast = null"
|
||||
>
|
||||
<FlexboxLayout minHeight="48" alignItems="center">
|
||||
<Label class="title msg" :text="toast" />
|
||||
</FlexboxLayout>
|
||||
</GridLayout>
|
||||
<Toast :toast="toast" :action="hideToast" />
|
||||
<GridLayout
|
||||
v-show="progress"
|
||||
row="1"
|
||||
|
@ -75,12 +39,15 @@ import {
|
|||
getFileAccess,
|
||||
} from "@nativescript/core";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import ConfirmDialog from "../modal/ConfirmDialog.vue";
|
||||
import Confirm from "../modals/Confirm";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
import Toast from "../sub/Toast";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import { openOrCreate } from "@akylas/nativescript-sqlite";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
components: { OptionsList, Toast },
|
||||
data() {
|
||||
return {
|
||||
backupFolder: null,
|
||||
|
@ -103,18 +70,21 @@ export default {
|
|||
return [
|
||||
{},
|
||||
{
|
||||
type: "list",
|
||||
icon: "folder",
|
||||
title: "buFol",
|
||||
subTitle: this.backupFolder,
|
||||
action: this.setBackupFolder,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "exp",
|
||||
title: "expBu",
|
||||
subTitle: localize("buInfo"),
|
||||
action: this.exportCheck,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "imp",
|
||||
title: "impBu",
|
||||
subTitle: localize("impInfo"),
|
||||
|
@ -134,9 +104,8 @@ export default {
|
|||
"unlinkBrokenImages",
|
||||
"clearImportSummary",
|
||||
]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
const ContentResolver = Application.android.nativeApp.getContentResolver();
|
||||
this.backupFolder = ApplicationSettings.getString("backupFolder");
|
||||
if (
|
||||
|
@ -227,7 +196,7 @@ export default {
|
|||
this.progress = null;
|
||||
this.releaseBackEvent();
|
||||
let description = localize("buto", `"${filename}"`);
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "expSuc",
|
||||
description,
|
||||
|
@ -240,6 +209,7 @@ export default {
|
|||
openZipFile() {
|
||||
utils.getBackupFile().then((uri) => {
|
||||
if (uri) {
|
||||
knownFolders.temp().clear();
|
||||
let dest = knownFolders.temp().path;
|
||||
utils.Zip.unzip(uri, dest)
|
||||
.then((res) => res && this.validateZipContent(res, uri))
|
||||
|
@ -346,7 +316,7 @@ export default {
|
|||
this.progress = null;
|
||||
this.releaseBackEvent();
|
||||
knownFolders.temp().clear();
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "impFail",
|
||||
description,
|
||||
|
@ -366,7 +336,7 @@ export default {
|
|||
const db = openOrCreate(recipesDB);
|
||||
|
||||
// Import recipes
|
||||
db.select(`SELECT * FROM recipes`).then((res) => {
|
||||
db.select("SELECT * FROM recipes").then((res) => {
|
||||
this.importRecipesFromDB(res);
|
||||
});
|
||||
|
||||
|
@ -426,7 +396,7 @@ export default {
|
|||
Folder.fromPath(destPath);
|
||||
utils.Zip.unzip(uri, destPath).then((res) => {
|
||||
if (res) {
|
||||
// delete unzipped json files
|
||||
// delete unzipped data files
|
||||
Folder.fromPath(path.join(destPath, "EnRecipes"))
|
||||
.getEntities()
|
||||
.then((entities) => {
|
||||
|
@ -444,13 +414,12 @@ export default {
|
|||
showImportSummary() {
|
||||
this.progress = null;
|
||||
this.releaseBackEvent();
|
||||
knownFolders.temp().clear();
|
||||
let { found, imported, updated } = this.importSummary;
|
||||
let exists = Math.abs(found - imported - updated) + updated;
|
||||
let importedNote = `\n${localize("recI")} ${imported}`;
|
||||
let existsNote = `\n${localize("recE")} ${exists}`;
|
||||
let updatedNote = `\n${localize("recU")} ${updated}`;
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "impSuc",
|
||||
description: `${found} ${localize(
|
||||
|
@ -479,9 +448,8 @@ export default {
|
|||
},
|
||||
|
||||
// HELPERS
|
||||
touch({ object, action }, method) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") method();
|
||||
hideToast() {
|
||||
this.toast = null;
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,32 +1,7 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'intf' | L" />
|
||||
</v-template>
|
||||
<v-template if="$index == 4">
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.action)"
|
||||
>
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label :text="item.subTitle" class="sub" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<OptionsList title="intf" :items="items" />
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
|
@ -42,12 +17,14 @@ import {
|
|||
Frame,
|
||||
} from "@nativescript/core";
|
||||
import { localize, overrideLocale } from "@nativescript/localize";
|
||||
import ActionDialog from "../modal/ActionDialog.vue";
|
||||
import ConfirmDialog from "../modal/ConfirmDialog.vue";
|
||||
import Action from "../modals/Action";
|
||||
import Confirm from "../modals/Confirm";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
components: { OptionsList },
|
||||
data() {
|
||||
return {
|
||||
appLanguage: "English",
|
||||
|
@ -59,12 +36,14 @@ export default {
|
|||
return [
|
||||
{},
|
||||
{
|
||||
type: "list",
|
||||
icon: "lang",
|
||||
title: "lang",
|
||||
subTitle: this.appLanguage,
|
||||
action: this.selectAppLanguage,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "theme",
|
||||
title: "Theme",
|
||||
subTitle: localize(
|
||||
|
@ -73,6 +52,7 @@ export default {
|
|||
action: this.selectThemes,
|
||||
},
|
||||
{
|
||||
type: "list",
|
||||
icon: "layout",
|
||||
title: "listVM",
|
||||
subTitle: localize(this.layout),
|
||||
|
@ -84,14 +64,13 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(["setTheme", "setLayout"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
},
|
||||
// LANGUAGE SELECTION
|
||||
selectAppLanguage() {
|
||||
let languages = this.language.map((e) => e.title);
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "lang",
|
||||
list: [...languages],
|
||||
|
@ -102,7 +81,7 @@ export default {
|
|||
let locale = this.language.filter((e) => e.title === action)[0]
|
||||
.locale;
|
||||
if (currentLocale !== locale) {
|
||||
this.$showModal(ConfirmDialog, {
|
||||
this.$showModal(Confirm, {
|
||||
props: {
|
||||
title: "appRst",
|
||||
description: localize("nLangInfo"),
|
||||
|
@ -123,7 +102,7 @@ export default {
|
|||
},
|
||||
// THEME SELECTION
|
||||
selectThemes() {
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "Theme",
|
||||
list: ["Light", "Dark", "Black", "sysDef", "sysDefB"],
|
||||
|
@ -142,7 +121,7 @@ export default {
|
|||
},
|
||||
// LAYOUT MODE
|
||||
setLayoutMode() {
|
||||
this.$showModal(ActionDialog, {
|
||||
this.$showModal(Action, {
|
||||
props: {
|
||||
title: "listVM",
|
||||
list: ["detailed", "grid", "photogrid", "simple", "minimal"],
|
||||
|
@ -155,13 +134,8 @@ export default {
|
|||
}
|
||||
});
|
||||
},
|
||||
// HELPERS
|
||||
touch({ object, action }, method) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") method();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
created() {
|
||||
this.appLanguage = ApplicationSettings.getString(
|
||||
"appLanguage",
|
||||
localize("sysDef")
|
45
app/components/settings/MPSettings.vue
Normal file
45
app/components/settings/MPSettings.vue
Normal file
|
@ -0,0 +1,45 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<OptionsList title="Settings" :items="items" />
|
||||
<GridLayout row="1" class="appbar" rows="*" columns="auto, *">
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
|
||||
export default {
|
||||
components: { OptionsList },
|
||||
computed: {
|
||||
...mapState(["icon", "mondayFirst"]),
|
||||
items() {
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "week",
|
||||
title: "swm",
|
||||
checked: this.mondayFirst,
|
||||
action: this.toggleFirstDay,
|
||||
},
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setFirstDay"]),
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
},
|
||||
toggleFirstDay() {
|
||||
this.setFirstDay(!this.mondayFirst);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
69
app/components/settings/Options.vue
Normal file
69
app/components/settings/Options.vue
Normal file
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<OptionsList title="opts" :items="items" />
|
||||
<GridLayout
|
||||
v-show="!toast"
|
||||
row="1"
|
||||
class="appbar"
|
||||
rows="*"
|
||||
columns="auto, *"
|
||||
>
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
<Toast :toast="toast" :action="(toast = null)" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Observable } from "@nativescript/core";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
import Toast from "../sub/Toast";
|
||||
import * as utils from "~/shared/utils";
|
||||
|
||||
export default {
|
||||
components: { OptionsList, Toast },
|
||||
data() {
|
||||
return {
|
||||
toast: null,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["icon", "shakeEnabled"]),
|
||||
items() {
|
||||
return [
|
||||
{},
|
||||
{
|
||||
type: "switch",
|
||||
icon: "shuf",
|
||||
title: "sVw",
|
||||
subTitle: "sVwInfo",
|
||||
checked: this.shakeEnabled,
|
||||
action: this.toggleShake,
|
||||
},
|
||||
{},
|
||||
];
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(["setShake"]),
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
},
|
||||
|
||||
// SHAKE VIEW RANDOM RECIPE
|
||||
toggleShake() {
|
||||
let checked = this.shakeEnabled;
|
||||
if (checked && !utils.hasAccelerometer()) {
|
||||
this.toast = localize("noAccSensor");
|
||||
utils.timer(5, (val) => {
|
||||
if (!val) this.toast = val;
|
||||
});
|
||||
} else this.setShake(!checked);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -1,34 +1,9 @@
|
|||
<template>
|
||||
<Page @loaded="onPageLoad" actionBarHidden="true">
|
||||
<GridLayout rows="*, auto" columns="auto, *">
|
||||
<ListView
|
||||
colSpan="2"
|
||||
rowSpan="2"
|
||||
class="options-list"
|
||||
for="item in items"
|
||||
>
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="'rest' | L" />
|
||||
</v-template>
|
||||
<v-template if="$index == 5">
|
||||
<Label class="group-info sub tw" :text="'restInfo' | L" />
|
||||
</v-template>
|
||||
<v-template if="$index == 6">
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
<v-template>
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.type)"
|
||||
>
|
||||
<Label class="ico" :text="icon.reset" />
|
||||
<Label col="1" :text="item.title | L" class="info" />
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
<OptionsList title="rest" :items="items" :action="resetListItems" />
|
||||
<GridLayout
|
||||
v-show="!toast"
|
||||
:hidden="toast"
|
||||
row="1"
|
||||
class="appbar"
|
||||
@loaded="onAppBarLoad"
|
||||
|
@ -36,18 +11,7 @@
|
|||
>
|
||||
<Button class="ico" :text="icon.back" @tap="$navigateBack()" />
|
||||
</GridLayout>
|
||||
<GridLayout
|
||||
v-show="toast"
|
||||
row="1"
|
||||
colSpan="2"
|
||||
class="appbar snackBar"
|
||||
columns="*"
|
||||
@swipe="hideToast"
|
||||
>
|
||||
<FlexboxLayout minHeight="48" alignItems="center">
|
||||
<Label class="title msg" :text="toast" />
|
||||
</FlexboxLayout>
|
||||
</GridLayout>
|
||||
<Toast :toast="toast" :action="hideToast" />
|
||||
</GridLayout>
|
||||
</Page>
|
||||
</template>
|
||||
|
@ -57,7 +21,10 @@ import { Observable, CoreTypes } from "@nativescript/core";
|
|||
import { localize } from "@nativescript/localize";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import * as utils from "~/shared/utils";
|
||||
import OptionsList from "../sub/OptionsList";
|
||||
import Toast from "../sub/Toast";
|
||||
export default {
|
||||
components: { OptionsList, Toast },
|
||||
data() {
|
||||
return {
|
||||
toast: null,
|
||||
|
@ -70,20 +37,28 @@ export default {
|
|||
return [
|
||||
{},
|
||||
{
|
||||
type: "cuisines",
|
||||
type: "list",
|
||||
icon: "reset",
|
||||
title: "restCuiL",
|
||||
data: "cuisines",
|
||||
},
|
||||
{
|
||||
type: "categories",
|
||||
type: "list",
|
||||
icon: "reset",
|
||||
title: "restCatL",
|
||||
data: "categories",
|
||||
},
|
||||
{
|
||||
type: "yieldUnits",
|
||||
type: "list",
|
||||
icon: "reset",
|
||||
title: "restYUL",
|
||||
data: "yieldUnits",
|
||||
},
|
||||
{
|
||||
type: "units",
|
||||
type: "list",
|
||||
icon: "reset",
|
||||
title: "restUL",
|
||||
data: "units",
|
||||
},
|
||||
{},
|
||||
{},
|
||||
|
@ -92,9 +67,8 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(["resetListItemsAction"]),
|
||||
onPageLoad(args) {
|
||||
const page = args.object;
|
||||
page.bindingContext = new Observable();
|
||||
onPageLoad({ object }) {
|
||||
object.bindingContext = new Observable();
|
||||
},
|
||||
onAppBarLoad({ object }) {
|
||||
this.appbar = object;
|
||||
|
@ -111,6 +85,7 @@ export default {
|
|||
});
|
||||
},
|
||||
hideToast({ object }) {
|
||||
this.appbar.translateY = 64;
|
||||
object
|
||||
.animate({
|
||||
opacity: 0,
|
||||
|
@ -120,7 +95,7 @@ export default {
|
|||
})
|
||||
.then(() => {
|
||||
this.showUndo = false;
|
||||
this.appbar.translateY = 64;
|
||||
this.toast = null;
|
||||
this.appbar.animate({
|
||||
translate: { x: 0, y: 0 },
|
||||
duration: 250,
|
||||
|
@ -128,13 +103,8 @@ export default {
|
|||
});
|
||||
object.opacity = 1;
|
||||
object.translateY = 0;
|
||||
this.toast = null;
|
||||
});
|
||||
},
|
||||
touch({ object, action }, type) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") this.resetListItems(type);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
62
app/components/sub/OptionsList.vue
Normal file
62
app/components/sub/OptionsList.vue
Normal file
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<ListView colSpan="2" rowSpan="2" class="options-list" for="item in items">
|
||||
<v-template if="$index == 0">
|
||||
<Label class="pageTitle" :text="title | L" />
|
||||
</v-template>
|
||||
<v-template if="item.type == 'switch'">
|
||||
<GridLayout
|
||||
columns="auto, *, auto"
|
||||
class="option"
|
||||
@touch="touch($event, item.data, item.action)"
|
||||
>
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1" verticalAlignment="center">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label v-if="item.subTitle" :text="item.subTitle | L" class="sub" />
|
||||
</StackLayout>
|
||||
<Switch
|
||||
isUserInteractionEnabled="false"
|
||||
:color="item.checked ? '#ff5200' : '#adb5bd'"
|
||||
col="2"
|
||||
:checked="item.checked"
|
||||
/>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template if="item.type == 'list'">
|
||||
<GridLayout
|
||||
columns="auto, *"
|
||||
class="option"
|
||||
@touch="touch($event, item.data, item.action)"
|
||||
>
|
||||
<Label class="ico" :text="icon[item.icon]" />
|
||||
<StackLayout col="1">
|
||||
<Label :text="item.title | L" class="info" />
|
||||
<Label v-if="item.subTitle" :text="item.subTitle" class="sub" />
|
||||
</StackLayout>
|
||||
</GridLayout>
|
||||
</v-template>
|
||||
<v-template if="item.type == 'info'">
|
||||
<Label class="group-info sub tw" :text="item.title | L" />
|
||||
</v-template>
|
||||
<v-template>
|
||||
<StackLayout class="listSpace"> </StackLayout>
|
||||
</v-template>
|
||||
</ListView>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
props: ["title", "items", "action"],
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
methods: {
|
||||
touch({ object, action }, data, localAction) {
|
||||
object.className = action.match(/down|move/) ? "option fade" : "option";
|
||||
if (action == "up") localAction ? localAction(data) : this.action(data);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
23
app/components/sub/SnackBar.vue
Normal file
23
app/components/sub/SnackBar.vue
Normal file
|
@ -0,0 +1,23 @@
|
|||
<template>
|
||||
<GridLayout
|
||||
row="1"
|
||||
class="appbar snackBar"
|
||||
columns="auto, *, auto"
|
||||
@swipe="action"
|
||||
>
|
||||
<Button :text="count" class="ico countdown tb" />
|
||||
<Label class="title" col="1" :text="msg | L" />
|
||||
<Button class="ico fab" :text="icon.undo" @tap="undo" col="3" />
|
||||
</GridLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
|
||||
export default {
|
||||
props: ["count", "msg", "undo", "action"],
|
||||
computed: {
|
||||
...mapState(["icon"]),
|
||||
},
|
||||
};
|
||||
</script>
|
|
@ -48,7 +48,7 @@
|
|||
import { ApplicationSettings, Application } from "@nativescript/core";
|
||||
import { localize } from "@nativescript/localize";
|
||||
import { mapState, mapActions } from "vuex";
|
||||
import ActionDialogWithSearch from "./modal/ActionDialogWithSearch.vue";
|
||||
import ActionWithSearch from "../modals/ActionWithSearch";
|
||||
import * as utils from "~/shared/utils";
|
||||
import { EventBus } from "~/main";
|
||||
|
||||
|
@ -92,7 +92,7 @@ export default {
|
|||
methods: {
|
||||
...mapActions(["removeActiveTimer", "updateActiveTimer", "addTimerPreset"]),
|
||||
attachRecipe() {
|
||||
this.$showModal(ActionDialogWithSearch, {
|
||||
this.$showModal(ActionWithSearch, {
|
||||
props: {
|
||||
title: "selRec",
|
||||
recipes: this.recipes,
|
||||
|
@ -140,7 +140,7 @@ export default {
|
|||
},
|
||||
clearNotification() {
|
||||
Application.android.unregisterBroadcastReceiver("timer" + this.timer.id);
|
||||
utils.TimerNotification.clear(this.timer.id);
|
||||
utils.TimerNotif.clear(this.timer.id);
|
||||
},
|
||||
toggleProgress(bool) {
|
||||
this.togglePause(this.timer, bool);
|
20
app/components/sub/Toast.vue
Normal file
20
app/components/sub/Toast.vue
Normal file
|
@ -0,0 +1,20 @@
|
|||
<template>
|
||||
<GridLayout
|
||||
v-show="toast"
|
||||
row="1"
|
||||
colSpan="2"
|
||||
class="appbar snackBar"
|
||||
columns="*"
|
||||
@swipe="action"
|
||||
>
|
||||
<FlexboxLayout minHeight="48" alignItems="center">
|
||||
<Label class="title msg" :text="toast" />
|
||||
</FlexboxLayout>
|
||||
</GridLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: ["toast", "action"],
|
||||
};
|
||||
</script>
|
|
@ -309,5 +309,6 @@
|
|||
"hour": "hour",
|
||||
"hours": "hours",
|
||||
"seconds": "seconds",
|
||||
"tmrClr": "Timer cleared"
|
||||
"tmrRm": "Timer removed",
|
||||
"notifSetg": "Notification settings"
|
||||
}
|
||||
|
|
24
app/main.ts
24
app/main.ts
|
@ -2,9 +2,27 @@ import {
|
|||
localize,
|
||||
androidLaunchEventLocalizationHandler,
|
||||
} from '@nativescript/localize'
|
||||
import { on, launchEvent } from '@nativescript/core/application'
|
||||
import { Application, AndroidApplication, Utils } from '@nativescript/core'
|
||||
|
||||
on(launchEvent, ({ android }) => {
|
||||
const keepScreenOn = () => {
|
||||
let ctx = Utils.ad.getApplicationContext()
|
||||
const pm = ctx.getSystemService(android.content.Context.POWER_SERVICE)
|
||||
let isScreenOff = !pm.isInteractive()
|
||||
if (isScreenOff) {
|
||||
console.log('keepScreenOn')
|
||||
const window = Application.android.startActivity.getWindow()
|
||||
const windowMgr = android.view.WindowManager
|
||||
window.addFlags(
|
||||
windowMgr.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||
windowMgr.LayoutParams.FLAG_TURN_SCREEN_ON |
|
||||
windowMgr.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
)
|
||||
}
|
||||
}
|
||||
Application.on(Application.resumeEvent, keepScreenOn)
|
||||
|
||||
Application.on(Application.launchEvent, ({ android }) => {
|
||||
console.log('launching')
|
||||
if (android) androidLaunchEventLocalizationHandler()
|
||||
})
|
||||
|
||||
|
@ -17,7 +35,7 @@ export const EventBus = new Vue()
|
|||
import CollectionView from '@nativescript-community/ui-collectionview/vue'
|
||||
Vue.use(CollectionView)
|
||||
|
||||
import { lvMixin } from './shared/mixins.js'
|
||||
import { lvMixin } from './shared/mixins'
|
||||
Vue.mixin(lvMixin)
|
||||
|
||||
Vue.config.silent = false
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="__PACKAGE__" android:versionCode="10000" android:versionName="1.0">
|
||||
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.INTERNET" tools:node="remove" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" tools:node="remove" />
|
||||
<application android:extractNativeLibs="true" android:name="com.tns.NativeScriptApplication" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:hardwareAccelerated="true" android:largeHeap="true" android:theme="@style/AppTheme">
|
||||
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:launchMode="singleTop" android:screenOrientation="userPortrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize">
|
||||
<activity android:name="com.tns.NativeScriptActivity" android:label="@string/title_activity_kimera" android:launchMode="singleInstance" android:screenOrientation="userPortrait" android:configChanges="keyboard|keyboardHidden|orientation|screenSize|smallestScreenSize|screenLayout|locale|uiMode" android:theme="@style/LaunchScreenTheme" android:windowSoftInputMode="adjustResize">
|
||||
<meta-data android:name="SET_THEME_ON_LAUNCH" android:resource="@style/AppTheme" />
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -19,6 +20,7 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name="com.tns.ErrorReportActivity" />
|
||||
<service android:name="com.tns.ForegroundService" android:enabled="true" android:exported="false" />
|
||||
<provider android:name="androidx.core.content.FileProvider" android:exported="false" android:authorities="${applicationId}.provider" android:grantUriPermissions="true">
|
||||
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider" />
|
||||
</provider>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"أضف"</string>
|
||||
<string name="About">"حول"</string>
|
||||
<string name="aap">"ألحق صورة"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -90,7 +90,8 @@
|
|||
<string name="allTs">"Totes les etiquetes"</string>
|
||||
<string name="allCats">"Totes les categories"</string>
|
||||
<string name="About">"Quant a"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="aD">"All done!"</string>
|
||||
<string name="aBtn">"ADD"</string>
|
||||
<string name="aap">"Attach a photo"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="American">"American"</string>
|
||||
<string name="aD">"Fuldendt!"</string>
|
||||
<string name="About">"Om"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"HINZUFÜGEN"</string>
|
||||
<string name="About">"Über"</string>
|
||||
<string name="aap">"Foto anhängen"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"ADD"</string>
|
||||
<string name="About">"About"</string>
|
||||
<string name="aap">"Attach a photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"ADD"</string>
|
||||
<string name="About">"About"</string>
|
||||
<string name="aap">"Attach a photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
<string name="aStpBtn">"AGREGAR PASO"</string>
|
||||
<string name="August">"Agosto"</string>
|
||||
<string name="sec">"s"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="title_activity_kimera">"EnRecipes"</string>
|
||||
<string name="allTs">"All Tags"</string>
|
||||
<string name="allCuis">"All Cuisines"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AÑADIR"</string>
|
||||
<string name="About">"Acerca de"</string>
|
||||
<string name="aap">"Adjuntar una foto"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -309,8 +309,10 @@
|
|||
<string name="aBtn">"LISÄÄ"</string>
|
||||
<string name="About">"Tietoja"</string>
|
||||
<string name="aap">"Liitä valokuva"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="tmrvbrt">"Timer vibrate"</string>
|
||||
<string name="delay">"Delay"</string>
|
||||
<string name="strtBtn">"START"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AJOUTER"</string>
|
||||
<string name="About">"À propos"</string>
|
||||
<string name="aap">"Joindre une photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AJOUTER"</string>
|
||||
<string name="About">"À propos"</string>
|
||||
<string name="aap">"Joindre une photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AJOUTER"</string>
|
||||
<string name="About">"À propos"</string>
|
||||
<string name="aap">"Joindre une photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AJOUTER"</string>
|
||||
<string name="About">"À propos"</string>
|
||||
<string name="aap">"Joindre une photo"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"जोड़ें"</string>
|
||||
<string name="About">"तकरीबन"</string>
|
||||
<string name="aap">"एक तस्वीर लगाओ"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"Tambah"</string>
|
||||
<string name="About">"Tentang"</string>
|
||||
<string name="aap">"Lampirkan foto"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"AGGIUNGI"</string>
|
||||
<string name="About">"Informazioni"</string>
|
||||
<string name="aap">"Allega una foto"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -289,7 +289,8 @@
|
|||
<string name="aBtn">"追加"</string>
|
||||
<string name="About">"アプリについて"</string>
|
||||
<string name="aap">"写真を添付"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="_app_name_1k3Sbz">"EnRecipes"</string>
|
||||
<string name="app_name">"EnRecipes"</string>
|
||||
<string name="title_activity_kimera">"EnRecipes"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="aBtn">"ADD"</string>
|
||||
<string name="About">"About"</string>
|
||||
<string name="aap">"Attach a photo"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -293,7 +293,8 @@
|
|||
<string name="aBtn">"ചേർക്കുക"</string>
|
||||
<string name="About">"കുറിച്ച്"</string>
|
||||
<string name="aap">"ഒരു ഫോട്ടോ അറ്റാച്ചുചെയ്യുക"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="ntmr">"New timer"</string>
|
||||
<string name="timer">"Cooking Timer"</string>
|
||||
<string name="sec">"sec"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -294,7 +294,8 @@
|
|||
<string name="aBtn">"Legg til"</string>
|
||||
<string name="About">"Om"</string>
|
||||
<string name="aap">"Legg ved et bilde"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="strtBtn">"START"</string>
|
||||
<string name="ntmr">"New timer"</string>
|
||||
<string name="timer">"Cooking Timer"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"TOEVOEGEN"</string>
|
||||
<string name="About">"Over"</string>
|
||||
<string name="aap">"Foto bijvoegen"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aD">"Tudo feito!"</string>
|
||||
<string name="aBtn">"ADICIONAR"</string>
|
||||
<string name="About">"Sobre"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="American">"Americana"</string>
|
||||
<string name="About">"Sobre"</string>
|
||||
<string name="aap">"Anexar uma fotografia"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -313,4 +313,6 @@
|
|||
<string name="aBtn">"ДОБАВИТЬ"</string>
|
||||
<string name="About">"О приложении"</string>
|
||||
<string name="aap">"Прикрепить фото"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
</resources>
|
||||
|
|
|
@ -293,7 +293,8 @@
|
|||
<string name="aBtn">"சேர்"</string>
|
||||
<string name="About">"பற்றி"</string>
|
||||
<string name="aap">"புகைப்படத்தை இணைக்கவும்"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="ntmr">"New timer"</string>
|
||||
<string name="timer">"Cooking Timer"</string>
|
||||
<string name="sec">"sec"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -293,7 +293,8 @@
|
|||
<string name="aBtn">"చేర్చు"</string>
|
||||
<string name="About">"గురించి"</string>
|
||||
<string name="aap">"ఫోటోను అటాచ్ చేయండి"</string>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="ntmr">"New timer"</string>
|
||||
<string name="timer">"Cooking Timer"</string>
|
||||
<string name="sec">"sec"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="tmrClr">"Timer cleared"</string>
|
||||
<string name="notifSetg">"Notification settings"</string>
|
||||
<string name="tmrRm">"Timer removed"</string>
|
||||
<string name="seconds">"seconds"</string>
|
||||
<string name="hours">"hours"</string>
|
||||
<string name="hour">"hour"</string>
|
||||
|
@ -313,4 +314,5 @@
|
|||
<string name="aBtn">"ADD"</string>
|
||||
<string name="About">"About"</string>
|
||||
<string name="aap">"Attach a photo"</string>
|
||||
<string name="tmrClr">"tmrClr"</string>
|
||||
</resources>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
declare const android: any
|
||||
|
||||
export const lvMixin = {
|
||||
methods: {
|
||||
transparentPage({ object }) {
|
|
@ -8,6 +8,8 @@ import {
|
|||
knownFolders,
|
||||
} from '@nativescript/core'
|
||||
let timerOne
|
||||
declare const global, android, androidx, com, java, Array: any
|
||||
|
||||
export const restartApp = () => {
|
||||
const ctx = Utils.ad.getApplicationContext()
|
||||
let mStartActivity = new android.content.Intent(
|
||||
|
@ -93,11 +95,12 @@ export const getRecipePhoto = () => {
|
|||
android.content.Intent.ACTION_GET_CONTENT
|
||||
)
|
||||
intent.setType('image/*')
|
||||
return callIntent(ctx, intent, 'Select photo', DIR_CODE).then((res) => {
|
||||
if (res.resultCode === android.app.Activity.RESULT_OK)
|
||||
if (res.intent != null && res.intent.getData())
|
||||
return res.intent.getData()
|
||||
})
|
||||
return callIntent(ctx, intent, 'Select photo', DIR_CODE).then(
|
||||
({ resultCode, intent }: any) => {
|
||||
if (resultCode === android.app.Activity.RESULT_OK)
|
||||
if (intent != null && intent.getData()) return intent.getData()
|
||||
}
|
||||
)
|
||||
}
|
||||
export const copyPhotoToCache = (uri, filepath) => {
|
||||
const ContentResolver = Application.android.nativeApp.getContentResolver()
|
||||
|
@ -129,7 +132,7 @@ export const copyDBToExport = () => {
|
|||
const input = new java.io.FileInputStream(src)
|
||||
try {
|
||||
const output = new java.io.FileOutputStream(dst)
|
||||
let len
|
||||
let len: number
|
||||
let buffer = Array.create('byte', 1024)
|
||||
while ((len = input.read(buffer)) > 0) output.write(buffer, 0, len)
|
||||
} catch (error) {
|
||||
|
@ -147,11 +150,12 @@ export const getBackupFolder = () => {
|
|||
const intent = new android.content.Intent(
|
||||
android.content.Intent.ACTION_OPEN_DOCUMENT_TREE
|
||||
)
|
||||
return callIntent(ctx, intent, 'Select folder', DIR_CODE).then((res) => {
|
||||
if (res.resultCode === android.app.Activity.RESULT_OK)
|
||||
if (res.intent != null && res.intent.getData())
|
||||
return res.intent.getData()
|
||||
})
|
||||
return callIntent(ctx, intent, 'Select folder', DIR_CODE).then(
|
||||
({ resultCode, intent }: any) => {
|
||||
if (resultCode === android.app.Activity.RESULT_OK)
|
||||
if (intent != null && intent.getData()) return intent.getData()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// BACKUP FILE PICKER
|
||||
|
@ -165,10 +169,9 @@ export const getBackupFile = () => {
|
|||
intent.addCategory(android.content.Intent.CATEGORY_OPENABLE)
|
||||
intent.setType('application/zip')
|
||||
return callIntent(ctx, intent, 'Select file to import', DIR_CODE).then(
|
||||
(res) => {
|
||||
if (res.resultCode === android.app.Activity.RESULT_OK) {
|
||||
if (res.intent != null && res.intent.getData())
|
||||
return res.intent.getData()
|
||||
({ resultCode, intent }: any) => {
|
||||
if (resultCode === android.app.Activity.RESULT_OK) {
|
||||
if (intent != null && intent.getData()) return intent.getData()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -176,7 +179,7 @@ export const getBackupFile = () => {
|
|||
|
||||
// ZIP OPERATIONS
|
||||
export class Zip {
|
||||
static getSubFiles(src, isRootFolder) {
|
||||
static getSubFiles(src: string, isRootFolder?: boolean) {
|
||||
const fileList = new java.util.ArrayList()
|
||||
const sourceFile = new java.io.File(src)
|
||||
let tempList = sourceFile.listFiles()
|
||||
|
@ -301,8 +304,8 @@ export const shareImage = (image, subject) => {
|
|||
}
|
||||
|
||||
// TIMER NOTIFICATION
|
||||
export class TimerNotification {
|
||||
static getResource(ctx, icon) {
|
||||
export class TimerNotif {
|
||||
static getIcon(ctx, icon) {
|
||||
const packageName = ctx.getApplicationInfo().packageName
|
||||
let resources = ctx.getResources()
|
||||
return (
|
||||
|
@ -328,36 +331,33 @@ export class TimerNotification {
|
|||
sound,
|
||||
title,
|
||||
vibrate,
|
||||
}: {
|
||||
actions?: boolean
|
||||
bID: string
|
||||
cID: string
|
||||
cName: string
|
||||
description: string
|
||||
nID: number
|
||||
priority: number
|
||||
sound: string
|
||||
title: string
|
||||
vibrate?: number
|
||||
}) {
|
||||
let sdkv = Device.sdkVersion * 1
|
||||
let soundUri
|
||||
let sdkv: number = parseInt(Device.sdkVersion)
|
||||
let soundUri: any
|
||||
if (sound) soundUri = new android.net.Uri.parse(sound)
|
||||
const NotifyMgr = android.app.NotificationManager
|
||||
let ctx = Utils.ad.getApplicationContext()
|
||||
const NotifySrv = ctx.getSystemService(
|
||||
android.content.Context.NOTIFICATION_SERVICE
|
||||
)
|
||||
|
||||
if (priority) {
|
||||
// Show over lock screen
|
||||
Application.android.on(AndroidApplication.activityResumedEvent, () => {
|
||||
const window = Application.android.startActivity.getWindow()
|
||||
const windowMgr = android.view.WindowManager
|
||||
window.addFlags(
|
||||
windowMgr.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||
windowMgr.LayoutParams.FLAG_TURN_SCREEN_ON |
|
||||
windowMgr.LayoutParams.FLAG_KEEP_SCREEN_ON
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (sdkv >= 26) {
|
||||
const importance = priority
|
||||
? NotifyMgr.IMPORTANCE_HIGH
|
||||
: NotifyMgr.IMPORTANCE_DEFAULT
|
||||
const importance =
|
||||
priority > 0 ? NotifyMgr.IMPORTANCE_HIGH : NotifyMgr.IMPORTANCE_MIN
|
||||
console.log(priority, importance)
|
||||
const AudioAttributes = android.media.AudioAttributes
|
||||
const audioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.build()
|
||||
const Channel = new android.app.NotificationChannel(
|
||||
|
@ -409,7 +409,8 @@ export class TimerNotification {
|
|||
|
||||
// CREATE NOTIFICATION
|
||||
const NotificationCompat = androidx.core.app.NotificationCompat
|
||||
let icon = TimerNotification.getResource(ctx, 'ic_stat_notify_silhouette')
|
||||
const AudioManager = android.media.AudioManager
|
||||
let icon = TimerNotif.getIcon(ctx, 'ic_stat_notify_silhouette')
|
||||
let builder = new NotificationCompat.Builder(ctx, cID)
|
||||
.setColor(new Color('#ff5200').android)
|
||||
.setContentIntent(mainPInt)
|
||||
|
@ -418,9 +419,10 @@ export class TimerNotification {
|
|||
.setPriority(priority)
|
||||
.setShowWhen(actions)
|
||||
.setSmallIcon(icon)
|
||||
.setSound(sound ? soundUri : null)
|
||||
.setTicker(title)
|
||||
.setAutoCancel(false)
|
||||
if (sound) builder.setSound(soundUri, AudioManager.STREAM_ALARM)
|
||||
else builder.setSound(null)
|
||||
if (description) builder.setContentText(description)
|
||||
if (vibrate) builder.setVibrate([500, 1000])
|
||||
if (actions) {
|
||||
|
@ -430,19 +432,20 @@ export class TimerNotification {
|
|||
builder.addAction(null, 'Stop', actionPInt2)
|
||||
}
|
||||
let notification = builder.build()
|
||||
notification.flags = NotificationCompat.FLAG_INSISTENT
|
||||
notification.flags =
|
||||
NotificationCompat.FLAG_INSISTENT | NotificationCompat.FLAG_ONGOING_EVENT
|
||||
NotifySrv.notify(nID, notification)
|
||||
}
|
||||
}
|
||||
|
||||
// GET RINGTONES LIST
|
||||
export const getTones = () => {
|
||||
let ctx = Utils.ad.getApplicationContext()
|
||||
let tones = []
|
||||
const RingtoneManager = android.media.RingtoneManager
|
||||
let ctx = Utils.ad.getApplicationContext()
|
||||
const ringtonesMgr = new RingtoneManager(ctx)
|
||||
ringtonesMgr.setType(RingtoneManager.TYPE_ALARM)
|
||||
const cursor = ringtonesMgr.getCursor()
|
||||
let tones = []
|
||||
while (cursor.moveToNext()) {
|
||||
tones.push({
|
||||
title: cursor.getString(RingtoneManager.TITLE_COLUMN_INDEX),
|
||||
|
@ -452,5 +455,21 @@ export const getTones = () => {
|
|||
cursor.getString(RingtoneManager.ID_COLUMN_INDEX),
|
||||
})
|
||||
}
|
||||
return tones
|
||||
|
||||
let defaultToneUri = RingtoneManager.getActualDefaultRingtoneUri(
|
||||
ctx,
|
||||
RingtoneManager.TYPE_ALARM
|
||||
)
|
||||
let defaultTone
|
||||
if (defaultToneUri) {
|
||||
let uriString = defaultToneUri.toString()
|
||||
let tonesAvailable = tones.filter((e) => e.uri == uriString)
|
||||
let toneExist = tonesAvailable.length
|
||||
defaultTone = {
|
||||
title: toneExist ? tonesAvailable[0].title : tones[0].title,
|
||||
uri: toneExist ? uriString : tones[0].uri,
|
||||
}
|
||||
}
|
||||
|
||||
return { tones, defaultTone: defaultToneUri ? defaultTone : tones[0] }
|
||||
}
|
|
@ -387,8 +387,7 @@ export default new Vuex.Store({
|
|||
title: sound.title,
|
||||
uri: sound.uri,
|
||||
}
|
||||
ApplicationSettings.setString('timerSoundTitle', sound.title)
|
||||
ApplicationSettings.setString('timerSoundUri', sound.uri)
|
||||
ApplicationSettings.setString('timerSound', JSON.stringify(sound))
|
||||
},
|
||||
setTimerVibrate(state, bool) {
|
||||
state.timerVibrate = bool
|
||||
|
@ -626,9 +625,7 @@ export default new Vuex.Store({
|
|||
)
|
||||
if (partition[0].length) createDocuments(partition[0])
|
||||
if (partition[1].length) updateDocuments(partition[1])
|
||||
} else {
|
||||
createDocuments(recipes)
|
||||
}
|
||||
} else createDocuments(recipes)
|
||||
state.importSummary.found = recipes.length
|
||||
state.importSummary.imported = imported
|
||||
state.importSummary.updated = updated
|
||||
|
|
2253
package-lock.json
generated
2253
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,7 +6,7 @@
|
|||
"lib": ["dom", "es2017"],
|
||||
"sourceMap": true,
|
||||
"noEmitHelpers": true,
|
||||
"importHelpers": true,
|
||||
"importHelpers": false, // Must be false to create custom android componentt
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["app/*"],
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
const webpack = require('@nativescript/webpack')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = (env) => {
|
||||
webpack.init(env)
|
||||
const platform = webpack.Utils.platform.getPlatformName()
|
||||
webpack.chainWebpack((config) => {
|
||||
if (platform === 'android') {
|
||||
const appComponents = [
|
||||
'@nativescript/core/ui/frame',
|
||||
'@nativescript/core/ui/frame/activity',
|
||||
path.resolve(__dirname, 'app/ForegroundService.js'),
|
||||
]
|
||||
appComponents.map((component) => {
|
||||
config.entry('bundle').add(component)
|
||||
})
|
||||
}
|
||||
})
|
||||
return webpack.resolveConfig()
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue