`);
var root_3 = /* @__PURE__ */ from_html(`🌍
Welcome to WeatherLens
`);
var root_4 = /* @__PURE__ */ from_html(`⏳
Loading weather data...
`);
-var root_5 = /* @__PURE__ */ from_html(``);
-var root_6 = /* @__PURE__ */ from_html(`
`, 1);
-var root_7 = /* @__PURE__ */ from_html(``);
+var root_5 = /* @__PURE__ */ from_html(` `);
+var root_6 = /* @__PURE__ */ from_html(``);
+var root_7 = /* @__PURE__ */ from_html(`
`, 1);
+var root_8 = /* @__PURE__ */ from_html(``);
function App($$anchor, $$props) {
push($$props, true);
let viewMode = /* @__PURE__ */ state(proxy(parseHash(typeof window !== "undefined" ? window.location.hash : "")));
@@ -8270,26 +8271,94 @@ function App($$anchor, $$props) {
window.addEventListener("hashchange", onHash);
return () => window.removeEventListener("hashchange", onHash);
});
- const SWIPE_THRESHOLD = 60;
- let touchAnchor = /* @__PURE__ */ state(null);
+ const SWIPE_THRESHOLD = 70;
+ const AXIS_THRESHOLD = 12;
+ const SWIPE_TIMEOUT = 160;
+ const TAB_LABELS = {
+ current: "Now",
+ hourly: "Hourly",
+ daily: "Daily",
+ detail: "More",
+ radar: "Radar"
+ };
+ let contentEl = /* @__PURE__ */ state(null);
+ let swiping = /* @__PURE__ */ state(false);
+ let swipeAnchor = /* @__PURE__ */ state(null);
+ let swipeDX = /* @__PURE__ */ state(0);
+ let swipeLock = /* @__PURE__ */ state(null);
+ let settling = /* @__PURE__ */ state(false);
+ const clampIdx = (i) => Math.min(Math.max(i, 0), VALID_VIEWS.length - 1);
+ const peekView = /* @__PURE__ */ user_derived(() => get(swiping) && get(swipeLock) === "x" && VALID_VIEWS.includes(get(viewMode)) ? VALID_VIEWS[clampIdx(VALID_VIEWS.indexOf(get(viewMode)) + (get(swipeDX) < 0 ? 1 : -1))] : null);
function onSwipeStart(e) {
if (get(viewMode) === "radar" || !e.touches || !e.touches[0]) return;
- set(touchAnchor, {
- x: e.touches[0].clientX,
- y: e.touches[0].clientY
+ const t = e.touches[0];
+ set(swipeAnchor, {
+ x: t.clientX,
+ y: t.clientY
}, true);
+ set(swipeDX, 0);
+ set(swipeLock, null);
+ set(settling, false);
+ set(swiping, true);
}
- function onSwipeEnd(e) {
- if (get(viewMode) === "radar" || !get(touchAnchor) || !e.changedTouches || !e.changedTouches[0]) return;
- const t = e.changedTouches[0];
- const dx = t.clientX - get(touchAnchor).x;
- const dy = t.clientY - get(touchAnchor).y;
- set(touchAnchor, null);
- if (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dx) < Math.abs(dy)) return;
- const idx = VALID_VIEWS.indexOf(get(viewMode));
- const next = VALID_VIEWS[Math.min(Math.max(idx + (dx < 0 ? 1 : -1), 0), VALID_VIEWS.length - 1)];
- if (next !== get(viewMode)) setView(next);
+ function onSwipeMove(e) {
+ if (!get(swiping) || !get(swipeAnchor)) return;
+ const t = e.touches[0];
+ const dx = t.clientX - get(swipeAnchor).x;
+ const dy = t.clientY - get(swipeAnchor).y;
+ if (!get(swipeLock)) {
+ if (Math.abs(dx) > AXIS_THRESHOLD && Math.abs(dx) > Math.abs(dy)) set(swipeLock, "x");
+ else if (Math.abs(dy) > AXIS_THRESHOLD) set(swipeLock, "y");
+ }
+ if (get(swipeLock) === "x") {
+ e.preventDefault();
+ set(swipeDX, dx);
+ } else if (get(swipeLock) === "y") set(swipeDX, 0);
}
+ function finishSwipe(e) {
+ if (!get(swiping)) return;
+ const t = e.changedTouches && e.changedTouches[0];
+ const dx = get(swipeLock) === "x" ? t ? t.clientX - get(swipeAnchor).x : get(swipeDX) : get(swipeDX);
+ const dy = t ? t.clientY - get(swipeAnchor).y : 0;
+ if (get(swipeLock) === "x" && Math.abs(dx) >= SWIPE_THRESHOLD && Math.abs(dx) >= Math.abs(dy) && get(viewMode) !== "radar") {
+ const idx = VALID_VIEWS.indexOf(get(viewMode));
+ const step = dx < 0 ? 1 : -1;
+ const next = VALID_VIEWS[clampIdx(idx + step)];
+ if (next !== get(viewMode)) {
+ set(settling, true);
+ set(swipeDX, (get(contentEl) ? get(contentEl).clientWidth : 420) * step * -1);
+ setTimeout(() => {
+ setView(next);
+ set(swiping, false);
+ set(swipeDX, 0);
+ set(swipeLock, null);
+ set(swipeAnchor, null);
+ set(settling, false);
+ }, SWIPE_TIMEOUT);
+ return;
+ }
+ }
+ set(settling, true);
+ set(swipeDX, 0);
+ setTimeout(() => {
+ set(swiping, false);
+ set(swipeLock, null);
+ set(swipeAnchor, null);
+ set(settling, false);
+ }, SWIPE_TIMEOUT);
+ }
+ function cancelSwipe(e) {
+ if (!get(swiping)) return;
+ set(settling, true);
+ set(swipeDX, 0);
+ setTimeout(() => {
+ set(swiping, false);
+ set(swipeLock, null);
+ set(swipeAnchor, null);
+ set(settling, false);
+ }, SWIPE_TIMEOUT);
+ }
+ const slideStyle = /* @__PURE__ */ user_derived(() => get(swipeDX) ? `transform: translateX(${get(swipeDX)}px)` : "");
let initDone = /* @__PURE__ */ state(false);
let geoError = /* @__PURE__ */ state("");
user_effect(() => {
@@ -8361,7 +8430,7 @@ function App($$anchor, $$props) {
const newest = updated[updated.length - 1];
if (newest) app$1.selectLocation(newest.id);
}
- var div = root_7();
+ var div = root_8();
var div_1 = child(div);
var button = child(div_1);
var text = child(button, true);
@@ -8441,8 +8510,8 @@ function App($$anchor, $$props) {
if (app$1.loading && !app$1.forecastData) $$render(consequent_4);
});
var node_8 = sibling(node_7, 2);
- var consequent_10 = ($$anchor) => {
- var fragment = root_6();
+ var consequent_11 = ($$anchor) => {
+ var fragment = root_7();
var div_8 = first_child(fragment);
var button_5 = child(div_8);
let classes_1;
@@ -8468,45 +8537,68 @@ function App($$anchor, $$props) {
let classes_10;
reset(div_9);
var div_10 = sibling(div_9, 2);
- var node_9 = child(div_10);
+ let classes_11;
+ var div_11 = child(div_10);
+ let classes_12;
+ var node_9 = child(div_11);
var consequent_5 = ($$anchor) => {
- var div_11 = root_5();
- CurrentWeather(child(div_11), {});
- reset(div_11);
- append($$anchor, div_11);
+ var span_3 = root_5();
+ let classes_13;
+ var text_5 = child(span_3, true);
+ reset(span_3);
+ template_effect(() => {
+ classes_13 = set_class(span_3, 1, "swipe-peek svelte-1n46o8q", null, classes_13, {
+ "from-left": get(swipeDX) >= 0,
+ "from-right": get(swipeDX) < 0
+ });
+ set_text(text_5, TAB_LABELS[get(peekView)]);
+ });
+ append($$anchor, span_3);
};
+ if_block(node_9, ($$render) => {
+ if (get(peekView) && TAB_LABELS[get(peekView)]) $$render(consequent_5);
+ });
+ var node_10 = sibling(node_9, 2);
var consequent_6 = ($$anchor) => {
- var div_12 = root_5();
- HourlyForecast(child(div_12), {});
+ var div_12 = root_6();
+ CurrentWeather(child(div_12), {});
reset(div_12);
append($$anchor, div_12);
};
var consequent_7 = ($$anchor) => {
- var div_13 = root_5();
- DailyForecast(child(div_13), {});
+ var div_13 = root_6();
+ HourlyForecast(child(div_13), {});
reset(div_13);
append($$anchor, div_13);
};
var consequent_8 = ($$anchor) => {
- var div_14 = root_5();
- WeatherDetail(child(div_14), {});
+ var div_14 = root_6();
+ DailyForecast(child(div_14), {});
reset(div_14);
append($$anchor, div_14);
};
var consequent_9 = ($$anchor) => {
- var div_15 = root_5();
- PrecipitationRadar(child(div_15), {});
+ var div_15 = root_6();
+ WeatherDetail(child(div_15), {});
reset(div_15);
append($$anchor, div_15);
};
- if_block(node_9, ($$render) => {
- if (get(viewMode) === "current") $$render(consequent_5);
- else if (get(viewMode) === "hourly") $$render(consequent_6, 1);
- else if (get(viewMode) === "daily") $$render(consequent_7, 2);
- else if (get(viewMode) === "detail") $$render(consequent_8, 3);
- else if (get(viewMode) === "radar") $$render(consequent_9, 4);
+ var consequent_10 = ($$anchor) => {
+ var div_16 = root_6();
+ PrecipitationRadar(child(div_16), {});
+ reset(div_16);
+ append($$anchor, div_16);
+ };
+ if_block(node_10, ($$render) => {
+ if (get(viewMode) === "current") $$render(consequent_6);
+ else if (get(viewMode) === "hourly") $$render(consequent_7, 1);
+ else if (get(viewMode) === "daily") $$render(consequent_8, 2);
+ else if (get(viewMode) === "detail") $$render(consequent_9, 3);
+ else if (get(viewMode) === "radar") $$render(consequent_10, 4);
});
+ reset(div_11);
reset(div_10);
+ bind_this(div_10, ($$value) => set(contentEl, $$value), () => get(contentEl));
template_effect(() => {
classes_1 = set_class(button_5, 1, "nav-btn svelte-1n46o8q", null, classes_1, { active: get(viewMode) === "current" });
classes_2 = set_class(button_6, 1, "nav-btn svelte-1n46o8q", null, classes_2, { active: get(viewMode) === "hourly" });
@@ -8518,6 +8610,9 @@ function App($$anchor, $$props) {
classes_8 = set_class(button_12, 1, "tab-btn svelte-1n46o8q", null, classes_8, { active: get(viewMode) === "daily" });
classes_9 = set_class(button_13, 1, "tab-btn svelte-1n46o8q", null, classes_9, { active: get(viewMode) === "detail" });
classes_10 = set_class(button_14, 1, "tab-btn svelte-1n46o8q", null, classes_10, { active: get(viewMode) === "radar" });
+ classes_11 = set_class(div_10, 1, "content-area svelte-1n46o8q", null, classes_11, { swiping: get(swiping) });
+ classes_12 = set_class(div_11, 1, "swipe-layer svelte-1n46o8q", null, classes_12, { settle: get(settling) });
+ set_style(div_11, get(slideStyle));
});
delegated("click", button_5, () => setView("current"));
delegated("click", button_6, () => setView("hourly"));
@@ -8530,22 +8625,24 @@ function App($$anchor, $$props) {
delegated("click", button_13, () => setView("detail"));
delegated("click", button_14, () => setView("radar"));
delegated("touchstart", div_10, onSwipeStart, void 0, true);
- delegated("touchend", div_10, onSwipeEnd);
+ delegated("touchmove", div_10, onSwipeMove, void 0, true);
+ delegated("touchend", div_10, finishSwipe);
+ event("touchcancel", div_10, cancelSwipe);
append($$anchor, fragment);
};
if_block(node_8, ($$render) => {
- if (app$1.forecastData && app$1.selectedLocation) $$render(consequent_10);
+ if (app$1.forecastData && app$1.selectedLocation) $$render(consequent_11);
});
reset(main);
- var node_15 = sibling(main, 2);
- var consequent_11 = ($$anchor) => {
+ var node_16 = sibling(main, 2);
+ var consequent_12 = ($$anchor) => {
SettingsDialog($$anchor, { onClose: () => app$1.showSettings = false });
};
- if_block(node_15, ($$render) => {
- if (app$1.showSettings) $$render(consequent_11);
+ if_block(node_16, ($$render) => {
+ if (app$1.showSettings) $$render(consequent_12);
});
- var node_16 = sibling(node_15, 2);
- var consequent_12 = ($$anchor) => {
+ var node_17 = sibling(node_16, 2);
+ var consequent_13 = ($$anchor) => {
AddLocationDialog($$anchor, {
onClose: () => {
app$1.showAddLocation = false;
@@ -8554,8 +8651,8 @@ function App($$anchor, $$props) {
onAdd: handleAddLocation
});
};
- if_block(node_16, ($$render) => {
- if (app$1.showAddLocation) $$render(consequent_12);
+ if_block(node_17, ($$render) => {
+ if (app$1.showAddLocation) $$render(consequent_13);
});
reset(div);
template_effect(() => {
@@ -8572,11 +8669,12 @@ function App($$anchor, $$props) {
delegate([
"click",
"touchstart",
+ "touchmove",
"touchend"
]);
//#endregion
//#region src/main.js
-console.info({ commit_hash: "93e5660a5c76fd41088193f5ca3e3a35cd7478b1" });
+console.info({ commit_hash: "09cea275b7ac2fd46d2184d84524ee1c3ddcbe60" });
mount(App, { target: document.getElementById("app") });
//#endregion