mirror of https://github.com/usememos/memos.git
feat(web,server): improve offline mode functionality
Enhance offline mode to fully support local-only operation: Frontend changes: - Hide OAuth login options when offline (SignIn.tsx) OAuth providers require external internet access and won't work offline, so they're now hidden when network is unavailable - Coordinate inputs already available in LocationDialog for manual entry Users can enter lat/lng directly when map tiles don't load Backend changes: - Add better logging for webhook network failures (webhook.go) Webhooks already fail gracefully via async goroutines, now with clearer logging to indicate network may be offline The app now functions fully offline for core features when both frontend and backend are running on local network: - Local username/password auth works (OAuth hidden) - All memo operations work (webhooks logged but don't block) - Maps allow coordinate input (tiles unavailable but functional) - Geocoding falls back to coordinates (already implemented)
This commit is contained in:
parent
7717f84afe
commit
923a346eac
|
|
@ -47,6 +47,11 @@ func Post(requestPayload *WebhookRequestPayload) error {
|
|||
}
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
// Log network errors but don't fail the operation - webhooks are optional
|
||||
slog.Warn("Failed to post webhook (network may be offline)",
|
||||
slog.String("url", requestPayload.URL),
|
||||
slog.String("activityType", requestPayload.ActivityType),
|
||||
slog.Any("err", err))
|
||||
return errors.Wrapf(err, "failed to post webhook to %s", requestPayload.URL)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { Separator } from "@/components/ui/separator";
|
|||
import { identityProviderServiceClient } from "@/grpcweb";
|
||||
import { absolutifyLink } from "@/helpers/utils";
|
||||
import useCurrentUser from "@/hooks/useCurrentUser";
|
||||
import { useOfflineDetection } from "@/hooks/useOfflineDetection";
|
||||
import { Routes } from "@/router";
|
||||
import { instanceStore } from "@/store";
|
||||
import { extractIdentityProviderIdFromName } from "@/store/common";
|
||||
|
|
@ -19,6 +20,7 @@ import { storeOAuthState } from "@/utils/oauth";
|
|||
const SignIn = observer(() => {
|
||||
const t = useTranslate();
|
||||
const currentUser = useCurrentUser();
|
||||
const isOffline = useOfflineDetection();
|
||||
const [identityProviderList, setIdentityProviderList] = useState<IdentityProvider[]>([]);
|
||||
const instanceGeneralSetting = instanceStore.state.generalSetting;
|
||||
|
||||
|
|
@ -87,7 +89,7 @@ const SignIn = observer(() => {
|
|||
</Link>
|
||||
</p>
|
||||
)}
|
||||
{identityProviderList.length > 0 && (
|
||||
{identityProviderList.length > 0 && !isOffline && (
|
||||
<>
|
||||
{!instanceGeneralSetting.disallowPasswordAuth && (
|
||||
<div className="relative my-4 w-full">
|
||||
|
|
|
|||
Loading…
Reference in New Issue