mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-05-31 12:15:42 -04:00
Fix/multiple bug reports (#1002)
* fix type issues for #999 * fix regression #995 * remove error from frontend and log error #996 * cleanup darkmode on login page * keep primary color bg
This commit is contained in:
parent
6ccffce320
commit
ccfaa02b03
@ -39,26 +39,29 @@
|
|||||||
<span> Locked by Owner </span>
|
<span> Locked by Owner </span>
|
||||||
</v-tooltip>
|
</v-tooltip>
|
||||||
|
|
||||||
<RecipeContextMenu
|
<ClientOnly>
|
||||||
show-print
|
<RecipeContextMenu
|
||||||
:menu-top="false"
|
show-print
|
||||||
:slug="slug"
|
:menu-top="false"
|
||||||
:menu-icon="$globals.icons.mdiDotsHorizontal"
|
:name="name"
|
||||||
fab
|
:slug="slug"
|
||||||
color="info"
|
:menu-icon="$globals.icons.mdiDotsHorizontal"
|
||||||
:card-menu="false"
|
fab
|
||||||
:recipe-id="recipeId"
|
color="info"
|
||||||
:use-items="{
|
:card-menu="false"
|
||||||
delete: false,
|
:recipe-id="recipeId"
|
||||||
edit: false,
|
:use-items="{
|
||||||
download: true,
|
delete: false,
|
||||||
mealplanner: true,
|
edit: false,
|
||||||
shoppingList: true,
|
download: true,
|
||||||
print: true,
|
mealplanner: true,
|
||||||
share: true,
|
shoppingList: true,
|
||||||
}"
|
print: true,
|
||||||
@print="$emit('print')"
|
share: true,
|
||||||
/>
|
}"
|
||||||
|
@print="$emit('print')"
|
||||||
|
/>
|
||||||
|
</ClientOnly>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="value" class="custom-btn-group mb-">
|
<div v-if="value" class="custom-btn-group mb-">
|
||||||
<v-btn
|
<v-btn
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
|
import { computed, defineComponent, useContext } from "@nuxtjs/composition-api";
|
||||||
import { useUserApi } from "~/composables/api";
|
import { useUserApi } from "~/composables/api";
|
||||||
import {UserOut} from "~/types/api-types/user";
|
import { UserOut } from "~/types/api-types/user";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
slug: {
|
slug: {
|
||||||
@ -49,19 +49,15 @@ export default defineComponent({
|
|||||||
const isFavorite = computed(() => user.value?.favoriteRecipes?.includes(props.slug));
|
const isFavorite = computed(() => user.value?.favoriteRecipes?.includes(props.slug));
|
||||||
|
|
||||||
async function toggleFavorite() {
|
async function toggleFavorite() {
|
||||||
console.log("Favorited?");
|
|
||||||
if (!isFavorite.value) {
|
if (!isFavorite.value) {
|
||||||
await api.users.addFavorite(user.value?.id, props.slug);
|
await api.users.addFavorite(user.value?.id, props.slug);
|
||||||
} else {
|
} else {
|
||||||
await api.users.removeFavorite(user.value?.id, props.slug);
|
await api.users.removeFavorite(user.value?.id, props.slug);
|
||||||
}
|
}
|
||||||
$auth.fetchUser();
|
$auth.fetchUser();
|
||||||
};
|
}
|
||||||
|
|
||||||
return { isFavorite, toggleFavorite };
|
return { isFavorite, toggleFavorite };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
</style>
|
|
||||||
|
@ -1,4 +1,18 @@
|
|||||||
import { IncomingMessage } from "connect";
|
import { IncomingMessage } from "connect";
|
||||||
|
import { useDark } from "@vueuse/core";
|
||||||
|
import { useContext } from "@nuxtjs/composition-api";
|
||||||
|
|
||||||
|
export const useToggleDarkMode = () => {
|
||||||
|
const isDark = useDark();
|
||||||
|
const { $vuetify } = useContext();
|
||||||
|
|
||||||
|
function toggleDark() {
|
||||||
|
isDark.value = !$vuetify.theme.dark;
|
||||||
|
$vuetify.theme.dark = !$vuetify.theme.dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
return toggleDark;
|
||||||
|
};
|
||||||
|
|
||||||
export const useAsyncKey = function () {
|
export const useAsyncKey = function () {
|
||||||
return String(Date.now());
|
return String(Date.now());
|
||||||
|
@ -62,11 +62,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, onMounted, ref, useContext } from "@nuxtjs/composition-api";
|
import { computed, defineComponent, onMounted, ref, useContext } from "@nuxtjs/composition-api";
|
||||||
import { useDark } from "@vueuse/core";
|
|
||||||
import AppHeader from "@/components/Layout/AppHeader.vue";
|
import AppHeader from "@/components/Layout/AppHeader.vue";
|
||||||
import AppSidebar from "@/components/Layout/AppSidebar.vue";
|
import AppSidebar from "@/components/Layout/AppSidebar.vue";
|
||||||
import TheSnackbar from "@/components/Layout/TheSnackbar.vue";
|
import TheSnackbar from "@/components/Layout/TheSnackbar.vue";
|
||||||
import { useCookbooks } from "~/composables/use-group-cookbooks";
|
import { useCookbooks } from "~/composables/use-group-cookbooks";
|
||||||
|
import { useToggleDarkMode } from "~/composables/use-utils";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { AppHeader, AppSidebar, TheSnackbar },
|
components: { AppHeader, AppSidebar, TheSnackbar },
|
||||||
@ -77,13 +77,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const isAdmin = computed(() => $auth.user?.admin);
|
const isAdmin = computed(() => $auth.user?.admin);
|
||||||
|
|
||||||
const isDark = useDark();
|
const toggleDark = useToggleDarkMode();
|
||||||
|
|
||||||
function toggleDark() {
|
|
||||||
isDark.value = !$vuetify.theme.dark;
|
|
||||||
$vuetify.theme.dark = !$vuetify.theme.dark;
|
|
||||||
console.log("toggleDark");
|
|
||||||
}
|
|
||||||
|
|
||||||
const sidebar = ref<boolean | null>(null);
|
const sidebar = ref<boolean | null>(null);
|
||||||
|
|
||||||
|
@ -45,10 +45,19 @@
|
|||||||
{{ $t("general.test") }}
|
{{ $t("general.test") }}
|
||||||
</BaseButton>
|
</BaseButton>
|
||||||
<template v-if="tested">
|
<template v-if="tested">
|
||||||
<v-divider class="my-x"></v-divider>
|
<v-divider class="my-x mt-6"></v-divider>
|
||||||
<v-card-text>
|
<v-card-text class="px-0">
|
||||||
Email Test Result: {{ success ? "Succeeded" : "Failed" }}
|
<h4>Email Test Results</h4>
|
||||||
<div>Errors: {{ error }}</div>
|
<span class="pl-4">
|
||||||
|
{{ success ? "Succeeded" : "Failed" }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<!-- <template v-if="errors">
|
||||||
|
<h4>Errors:</h4>
|
||||||
|
<span class="pl-4">
|
||||||
|
{{ errors }}
|
||||||
|
</span>
|
||||||
|
</template> -->
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
@ -296,5 +305,4 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
</style>
|
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-container fill-height fluid class="d-flex justify-center align-center" style="background: #f5f8fa">
|
<v-container
|
||||||
|
fill-height
|
||||||
|
fluid
|
||||||
|
class="d-flex justify-center align-center"
|
||||||
|
:class="{
|
||||||
|
'bg-off-white': !$vuetify.theme.dark,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<v-card tag="section" class="d-flex flex-column align-center" width="600px">
|
<v-card tag="section" class="d-flex flex-column align-center" width="600px">
|
||||||
<v-toolbar width="100%" color="primary" class="d-flex justify-center mb-4" dark>
|
<v-toolbar width="100%" color="primary" class="d-flex justify-center mb-4" dark>
|
||||||
<v-toolbar-title class="headline text-h4"> Mealie </v-toolbar-title>
|
<v-toolbar-title class="headline text-h4"> Mealie </v-toolbar-title>
|
||||||
@ -7,14 +14,12 @@
|
|||||||
|
|
||||||
<div class="icon-container">
|
<div class="icon-container">
|
||||||
<v-divider class="icon-divider"></v-divider>
|
<v-divider class="icon-divider"></v-divider>
|
||||||
<v-avatar size="102" color="grey lighten-2">
|
<v-avatar class="pa-2 icon-avatar" color="primary" size="100">
|
||||||
<v-avatar class="pa-2 icon-avatar" color="white" size="100">
|
<svg class="icon-white" style="width: 100px; height: 100px" viewBox="0 0 24 24">
|
||||||
<svg class="icon-primary" style="width: 100px; height: 100px" viewBox="0 0 24 24">
|
<path
|
||||||
<path
|
d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.36,10.22L13.16,10C12.38,9.23 12.38,7.97 13.16,7.19L17.5,2.82L18.43,3.74L15.19,7L16.15,7.94L19.39,4.69L20.31,5.61L17.06,8.85L18,9.81L21.26,6.56L22.18,7.5L17.81,11.84C17.03,12.62 15.77,12.62 15,11.84L14.78,11.64L13.41,13Z"
|
||||||
d="M8.1,13.34L3.91,9.16C2.35,7.59 2.35,5.06 3.91,3.5L10.93,10.5L8.1,13.34M13.41,13L20.29,19.88L18.88,21.29L12,14.41L5.12,21.29L3.71,19.88L13.36,10.22L13.16,10C12.38,9.23 12.38,7.97 13.16,7.19L17.5,2.82L18.43,3.74L15.19,7L16.15,7.94L19.39,4.69L20.31,5.61L17.06,8.85L18,9.81L21.26,6.56L22.18,7.5L17.81,11.84C17.03,12.62 15.77,12.62 15,11.84L14.78,11.64L13.41,13Z"
|
/>
|
||||||
/>
|
</svg>
|
||||||
</svg>
|
|
||||||
</v-avatar>
|
|
||||||
</v-avatar>
|
</v-avatar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -91,16 +96,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
||||||
|
<v-btn absolute bottom center @click="toggleDark">
|
||||||
|
<v-icon left>
|
||||||
|
{{ $vuetify.theme.dark ? $globals.icons.weatherSunny : $globals.icons.weatherNight }}
|
||||||
|
</v-icon>
|
||||||
|
{{ $vuetify.theme.dark ? "Light Mode" : "Dark Mode" }}
|
||||||
|
</v-btn>
|
||||||
</v-container>
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, ref, useContext, computed, reactive } from "@nuxtjs/composition-api";
|
import { defineComponent, ref, useContext, computed, reactive } from "@nuxtjs/composition-api";
|
||||||
import { alert } from "~/composables/use-toast";
|
import { alert } from "~/composables/use-toast";
|
||||||
|
import { useToggleDarkMode } from "~/composables/use-utils";
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
layout: "blank",
|
layout: "blank",
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
|
const toggleDark = useToggleDarkMode();
|
||||||
|
|
||||||
const { $auth } = useContext();
|
const { $auth } = useContext();
|
||||||
const context = useContext();
|
const context = useContext();
|
||||||
|
|
||||||
@ -147,6 +162,7 @@ export default defineComponent({
|
|||||||
loggingIn,
|
loggingIn,
|
||||||
allowSignup,
|
allowSignup,
|
||||||
authenticate,
|
authenticate,
|
||||||
|
toggleDark,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -167,6 +183,10 @@ export default defineComponent({
|
|||||||
fill: var(--v-primary-base);
|
fill: var(--v-primary-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-white {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
|
||||||
.icon-container {
|
.icon-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -185,4 +205,8 @@ export default defineComponent({
|
|||||||
border-color: rgba(0, 0, 0, 0.12);
|
border-color: rgba(0, 0, 0, 0.12);
|
||||||
border: 2px;
|
border: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bg-off-white {
|
||||||
|
background: #f5f8fa;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -504,10 +504,12 @@ export default defineComponent({
|
|||||||
async beforeRouteLeave(_to, _from, next) {
|
async beforeRouteLeave(_to, _from, next) {
|
||||||
const isSame = JSON.stringify(this.recipe) === JSON.stringify(this.originalRecipe);
|
const isSame = JSON.stringify(this.recipe) === JSON.stringify(this.originalRecipe);
|
||||||
|
|
||||||
console.log({ working: this.recipe, saved: this.originalRecipe });
|
|
||||||
|
|
||||||
if (this.form && !isSame && this.recipe?.slug !== undefined) {
|
if (this.form && !isSame && this.recipe?.slug !== undefined) {
|
||||||
if (window.confirm("You have unsaved changes. Do you want to save before leaving?")) {
|
if (
|
||||||
|
window.confirm(
|
||||||
|
"You have unsaved changes. Do you want to save before leaving?\n\nOkay to save, Cancel to discard changes."
|
||||||
|
)
|
||||||
|
) {
|
||||||
await this.api.recipes.updateOne(this.recipe.slug, this.recipe);
|
await this.api.recipes.updateOne(this.recipe.slug, this.recipe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -558,7 +560,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
invoke(async () => {
|
invoke(async () => {
|
||||||
await until(recipe).not.toBeNull();
|
await until(recipe).not.toBeNull();
|
||||||
|
|
||||||
originalRecipe.value = deepCopy(recipe.value);
|
originalRecipe.value = deepCopy(recipe.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -746,6 +747,7 @@ export default defineComponent({
|
|||||||
useMeta(metaData);
|
useMeta(metaData);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
originalRecipe,
|
||||||
createApiExtra,
|
createApiExtra,
|
||||||
apiNewKey,
|
apiNewKey,
|
||||||
enableLandscape,
|
enableLandscape,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { Plugin } from "@nuxt/types"
|
import { Plugin } from "@nuxt/types";
|
||||||
import { NuxtAxiosInstance } from "@nuxtjs/axios";
|
import { NuxtAxiosInstance } from "@nuxtjs/axios";
|
||||||
import { alert } from "~/composables/use-toast";
|
import { alert } from "~/composables/use-toast";
|
||||||
|
|
||||||
const toastPlugin: Plugin = ({ $axios }: { $axios: NuxtAxiosInstance }) => {
|
const toastPlugin: Plugin = ({ $axios }: { $axios: NuxtAxiosInstance }) => {
|
||||||
$axios.onResponse((response) => {
|
$axios.onResponse((response) => {
|
||||||
if (response.data.message) {
|
if (response?.data?.message) {
|
||||||
alert.info(response.data.message);
|
alert.info(response.data.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -13,6 +13,6 @@ const toastPlugin: Plugin = ({ $axios }: { $axios: NuxtAxiosInstance }) => {
|
|||||||
alert.error(error.response.data.detail.message);
|
alert.error(error.response.data.detail.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
export default toastPlugin;
|
export default toastPlugin;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
|
||||||
import emails
|
import emails
|
||||||
|
from emails.backend.response import SMTPResponse
|
||||||
|
|
||||||
from mealie.core.root_logger import get_logger
|
from mealie.core.root_logger import get_logger
|
||||||
from mealie.services._base_service import BaseService
|
from mealie.services._base_service import BaseService
|
||||||
@ -29,7 +30,10 @@ class DefaultEmailSender(ABCEmailSender, BaseService):
|
|||||||
smtp_options["user"] = self.settings.SMTP_USER
|
smtp_options["user"] = self.settings.SMTP_USER
|
||||||
if self.settings.SMTP_PASSWORD:
|
if self.settings.SMTP_PASSWORD:
|
||||||
smtp_options["password"] = self.settings.SMTP_PASSWORD
|
smtp_options["password"] = self.settings.SMTP_PASSWORD
|
||||||
response = message.send(to=email_to, smtp=smtp_options)
|
response: SMTPResponse = message.send(to=email_to, smtp=smtp_options)
|
||||||
logger.info(f"send email result: {response}")
|
logger.info(f"send email result: {response}")
|
||||||
|
|
||||||
|
if not response.success:
|
||||||
|
logger.error(f"send email error: {response.error}")
|
||||||
|
|
||||||
return response.status_code in [250]
|
return response.status_code in [250]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user