x1ongzhu 1 rok temu
rodzic
commit
95a0e7b86d

+ 20 - 0
android/app/release/output-metadata.json

@@ -0,0 +1,20 @@
+{
+  "version": 3,
+  "artifactType": {
+    "type": "APK",
+    "kind": "Directory"
+  },
+  "applicationId": "io.freeshort.freeshort",
+  "variantName": "release",
+  "elements": [
+    {
+      "type": "SINGLE",
+      "filters": [],
+      "attributes": [],
+      "versionCode": 1,
+      "versionName": "1.0",
+      "outputFile": "app-release.apk"
+    }
+  ],
+  "elementType": "File"
+}

BIN
android/zouma2024.keystore


+ 9 - 1
capacitor.config.ts

@@ -4,11 +4,19 @@ const config: CapacitorConfig = {
     appId: "io.freeshort.freeshort",
     appName: "FreeShort",
     webDir: "dist",
+    bundledWebRuntime: true,
     server: {
         androidScheme: "https",
         cleartext: true,
     },
-    android: {},
+    android: {
+        buildOptions: {
+            keystorePath: "./android/zouma2024.keystore",
+            keystorePassword: "3edc#EDC",
+            keystoreAlias: "zouma",
+            keystoreAliasPassword: "3edc#EDC",
+        },
+    },
 };
 
 export default config;

+ 2 - 6
index.html

@@ -20,15 +20,11 @@
     <meta name="apple-mobile-web-app-capable" content="yes" />
     <meta name="apple-mobile-web-app-title" content="Ionic App" />
     <meta name="apple-mobile-web-app-status-bar-style" content="black" />
-
-    <link
-        href="https://fonts.googleapis.com/css2?family=Lalezar&display=swap"
-        rel="stylesheet">
 </head>
 
-<body class="dark">
+<body class="dark text-sm">
     <div id="app">
-        <div class="absolute h-[40px] left-0 top-0 right-0 bottom-0 m-auto">
+        <div style="height: 40px; position: absolute; left: 0; top: 0; right: 0; bottom: 0; margin: auto; text-align: center;">
             <svg class="m-auto" width="40" height="40" stroke="#ffffffcc" viewBox="0 0 24 24"
                 xmlns="http://www.w3.org/2000/svg">
                 <style>

+ 1 - 1
src/assets/meta.json

@@ -1,4 +1,4 @@
 {
-    "version": 1,
+    "version": 2,
     "versionName": "1.0.0"
 }

+ 27 - 11
src/components/PlayView.vue

@@ -112,9 +112,9 @@
                         <IonIcon
                             :class="{ 'text-prim': saved }"
                             :icon="bookmark"
-                            class="text-4xl opacity-80"
+                            class="text-3xl opacity-80"
                         />
-                        <div class="text-xs">
+                        <div class="text-[0.65rem]">
                             {{ saved ? "Saved" : "Save" }}
                         </div>
                     </div>
@@ -124,9 +124,9 @@
                     >
                         <IonIcon
                             :icon="arrowRedo"
-                            class="text-4xl opacity-80"
+                            class="text-3xl opacity-80"
                         />
-                        <div class="text-xs">Share</div>
+                        <div class="text-[0.65rem]">Share</div>
                     </div>
                 </div>
             </div>
@@ -244,10 +244,18 @@ const props = defineProps({
     episodes: Array<any>,
     saved: Boolean,
 });
-const emit = defineEmits(["chooseEpisode", "save", "ended", "pay", "share"]);
+const emit = defineEmits([
+    "chooseEpisode",
+    "save",
+    "ended",
+    "pay",
+    "share",
+    "progress",
+]);
 const router = useIonRouter();
 const video: Ref<HTMLVideoElement | null> = ref(null);
-const { playing, currentTime, duration, volume } = useMediaControls(video);
+const { playing, currentTime, duration, volume, seeking } =
+    useMediaControls(video);
 const showPauseBtn = ref(false);
 const progress = computed(() => {
     if (isNaN(duration.value) || duration.value === 0) return 0;
@@ -310,7 +318,6 @@ const dragHandler = ({ movement: [x, y], dragging }: any) => {
         draggingData.dragging = false;
         currentTime.value = (duration.value * draggingData.toProgress) / 100;
     }
-    console.log(JSON.stringify(draggingData));
 };
 
 function getEpisode() {
@@ -334,6 +341,7 @@ function getEpisode() {
     }
     loading.value = false;
 }
+
 useDrag(dragHandler, {
     domTarget: dragTarget,
     eventOptions: {
@@ -352,6 +360,8 @@ onMounted(() => {
 });
 onBeforeUnmount(() => {
     emitter.off("payment-success", onPaymentSuccess);
+    clearTimeout(videoPlayTimeout.value);
+    clearTimeout(immersiveTimeout.value);
 });
 watch(
     () => props.episode,
@@ -416,6 +426,7 @@ function exitImmersive() {
 }
 
 function onVideoDidPlay() {
+    clearTimeout(videoPlayTimeout.value);
     videoPlayTimeout.value = setTimeout(enterImmersive, 3000);
 }
 
@@ -423,19 +434,24 @@ function onVideoDidPause() {
     exitImmersive();
 }
 
-function onVideoEnd() {}
-
 watchThrottled(
     currentTime,
     () => {
-        http.post("/playHistories", {
+        emit("progress", {
             seriesId: props.series?.id,
             episodeId: props.episode?.id,
             duration: currentTime.value,
         });
     },
-    { throttle: 3000 }
+    { throttle: 2000 }
 );
+
+function seek(n: number) {
+    console.log("seek", n);
+    if (isNaN(duration.value)) return;
+    currentTime.value = n;
+}
+defineExpose({ seek });
 </script>
 <style lang="less" scoped>
 .mask-info {

+ 4 - 4
src/components/ShareModal.vue

@@ -4,12 +4,12 @@
         :isOpen="showInviteModal"
         @didDismiss="showInviteModal = false"
     >
-        <div class="content-wrapper text-base font-bold">
+        <div class="content-wrapper">
             <div class="code-wrapper flex flex-col items-center justify-center">
-                <div class="font-bold">INVITE 3 FRIENDS</div>
-                <div class="">GET 7 DAYS FREE WATCHING</div>
+                <div class="">INVITE 3 FRIENDS</div>
+                <div class="font-bold">GET 7 DAYS FREE WATCHING</div>
                 <img class="mt-2" :src="qrcode" alt="QR Code" />
-                <div class="mt-2 font-bold">INVITED: 0</div>
+                <div class="mt-2">INVITED: 0</div>
             </div>
             <div class="flex mt-4 text-center text-sm">
                 <div

+ 3 - 6
src/main.ts

@@ -1,4 +1,4 @@
-import eruda from "eruda";
+import { showConsole } from "@/plugins/eruda";
 import { createApp } from "vue";
 import { createPinia } from "pinia";
 import App from "./App.vue";
@@ -32,11 +32,9 @@ import "swiper/css";
 /* Theme variables */
 import "./theme/variables.css";
 
-import "./theme/main.less";
+import "./styles/main.less";
 
-if (process.env.NODE_ENV === "development") {
-    eruda.init();
-}
+showConsole();
 
 if (Capacitor.isNativePlatform()) {
     StatusBar.setOverlaysWebView({ overlay: true });
@@ -47,7 +45,6 @@ if (Capacitor.isNativePlatform()) {
             // style.setProperty('--ion-safe-area-bottom', insets.bottom + 'px')
         });
     }
-    
 }
 checkUpdate();
 

+ 9 - 0
src/plugins/eruda.ts

@@ -0,0 +1,9 @@
+import eruda from "eruda";
+
+function showConsole(force = false) {
+    if (process.env.NODE_ENV === "development" || force) {
+        eruda.init();
+    }
+}
+
+export { showConsole };

+ 4 - 1
src/router/index.ts

@@ -51,6 +51,10 @@ const routes: Array<RouteRecordRaw> = [
         path: "/profile",
         component: () => import("@/views/ProfileView.vue"),
     },
+    {
+        path: "/feedback",
+        component: () => import("@/views/FeedbackView.vue"),
+    },
 ];
 
 const router = createRouter({
@@ -59,7 +63,6 @@ const router = createRouter({
 });
 
 router.beforeEach(async (to, from, next) => {
-    console.log("route change", to);
     // await new Promise((resolve) => setTimeout(resolve, 3000));
     const { user, setUser } = useUserStore();
     if (!user && to.name !== "login") {

BIN
src/styles/fonts/Lalezar-Regular.ttf


+ 6 - 0
src/theme/main.less → src/styles/main.less

@@ -8,3 +8,9 @@ ion-toast {
         color: var(--ion-color-danger-contrast);
     }
 }
+
+@font-face {
+    font-family: Lalezar;
+    src: url("./fonts/Lalezar-Regular.ttf");
+}
+

+ 76 - 0
src/views/FeedbackView.vue

@@ -0,0 +1,76 @@
+<template>
+    <IonPage>
+        <IonHeader>
+            <IonToolbar>
+                <IonButtons slot="start">
+                    <IonBackButton text="" />
+                </IonButtons>
+                <IonTitle>Feedback</IonTitle>
+            </IonToolbar>
+        </IonHeader>
+        <IonContent>
+            <div class="px-4 mt-8">
+                <textarea
+                    v-model="desc"
+                    placeholder="Feedback description"
+                    class="block bg-neutral-800 w-full p-4 rounded-md outline-prim h-28 resize-none"
+                />
+
+                <input
+                    v-model="email"
+                    inputmode="email"
+                    type="email"
+                    placeholder="Email address"
+                    class="mt-4 bg-neutral-800 h-10 w-full p-4 rounded-md outline-prim"
+                />
+
+                <button
+                    class="mt-6 w-full h-10 bg-prim text-white rounded-md font-bold"
+                    @click="submit"
+                >
+                    Submit
+                </button>
+            </div>
+        </IonContent>
+    </IonPage>
+</template>
+<script setup lang="ts">
+import toast from "@/plugins/toast";
+import {
+    IonPage,
+    IonContent,
+    IonHeader,
+    IonToolbar,
+    IonTitle,
+    IonLabel,
+    IonButtons,
+    IonBackButton,
+    useIonRouter,
+} from "@ionic/vue";
+import { isEmail } from "validator";
+import { ref } from "vue";
+const desc = ref("");
+const email = ref("");
+const router = useIonRouter();
+function submit() {
+    if (!desc.value) {
+        toast("Please enter feedback description", {
+            type: "error",
+        });
+        return;
+    }
+    if (!isEmail(email.value)) {
+        toast("Please enter a valid email address", {
+            type: "error",
+        });
+        return;
+    }
+    toast("Feedback submitted", {
+        type: "success",
+    });
+    setTimeout(() => {
+        router.back();
+    }, 1000);
+}
+</script>
+<style lang="less" scoped></style>

+ 1 - 0
src/views/HomeTab.vue

@@ -171,6 +171,7 @@ function detail(item: any) {
         margin: auto;
         font-weight: bold;
         --color: var(--ion-color-tertiary);
+        --border-radius: 10px;
     }
 }
 :deep(.swiper-pagination) {

+ 11 - 11
src/views/LoginView.vue

@@ -30,25 +30,25 @@
                             class="absolute top-0 left-0 w-full"
                         >
                             <div class="text-xl font-bold">Sign in</div>
-                            <div class="text-base">
+                            <div class="text-sm">
                                 <input
                                     type="text"
                                     inputmode="email"
-                                    class="w-full h-12 mt-6 rounded-md px-4 bg-neutral-800 active:border-2 focus:border-2 border-prim focus:border-prim outline-none"
+                                    class="w-full h-10 mt-6 rounded-md px-4 bg-neutral-800 outline-prim"
                                     placeholder="Email Address"
                                     v-model="loginForm.email"
                                 />
 
                                 <input
                                     type="password"
-                                    class="w-full h-12 mt-6 rounded-md px-4 bg-neutral-800 active:border-2 focus:border-2 border-prim focus:border-prim outline-none"
+                                    class="w-full h-10 mt-6 rounded-md px-4 bg-neutral-800 outline-prim"
                                     placeholder="Password (6-32 Characters)"
                                     v-model="loginForm.password"
                                 />
 
                                 <div class="mt-6 font-bold">
                                     <button
-                                        class="w-full h-12 bg-prim text-white rounded-md disabled:bg-opacity-50 disabled:text-opacity-50"
+                                        class="w-full h-10 bg-prim text-white rounded-md disabled:bg-opacity-50 disabled:text-opacity-50"
                                         :disabled="
                                             loginDisabled || loginForm.loading
                                         "
@@ -58,7 +58,7 @@
                                     </button>
 
                                     <button
-                                        class="w-full h-12 mt-6 bg-white text-black rounded-md"
+                                        class="w-full h-10 mt-6 bg-white text-black rounded-md"
                                         @click="mode = 1"
                                     >
                                         Create an account
@@ -70,32 +70,32 @@
                             <div class="text-xl font-bold">
                                 Create an account
                             </div>
-                            <div class="text-base">
+                            <div class="text-sm">
                                 <input
                                     type="text"
                                     inputmode="email"
-                                    class="w-full h-12 mt-6 rounded-md px-4 bg-neutral-800 active:border-2 focus:border-2 border-prim focus:border-prim outline-none"
+                                    class="w-full h-10 mt-6 rounded-md px-4 bg-neutral-800 outline-prim"
                                     placeholder="Email Address"
                                     v-model="registerForm.email"
                                 />
 
                                 <input
                                     type="password"
-                                    class="w-full h-12 mt-6 rounded-md px-4 bg-neutral-800 active:border-2 focus:border-2 border-prim focus:border-prim outline-none"
+                                    class="w-full h-10 mt-6 rounded-md px-4 bg-neutral-800 outline-prim"
                                     placeholder="Password (6-32 Characters)"
                                     v-model="registerForm.password"
                                 />
 
                                 <input
                                     type="password"
-                                    class="w-full h-12 mt-6 rounded-md px-4 bg-neutral-800 active:border-2 focus:border-2 border-prim focus:border-prim outline-none"
+                                    class="w-full h-10 mt-6 rounded-md px-4 bg-neutral-800 outline-prim"
                                     placeholder="Confirm Password"
                                     v-model="registerForm.confirmPassword"
                                 />
 
                                 <div class="mt-6 font-bold">
                                     <button
-                                        class="w-full h-12 bg-prim text-white rounded-md disabled:bg-opacity-50 disabled:text-opacity-50"
+                                        class="w-full h-10 bg-prim text-white rounded-md disabled:bg-opacity-50 disabled:text-opacity-50"
                                         :disabled="registerDisabled"
                                         @click="register"
                                     >
@@ -103,7 +103,7 @@
                                     </button>
 
                                     <button
-                                        class="w-full h-12 mt-6 bg-white text-black rounded-md"
+                                        class="w-full h-10 mt-6 bg-white text-black rounded-md"
                                         @click="mode = 0"
                                     >
                                         Sign in

+ 45 - 13
src/views/MeTab.vue

@@ -4,7 +4,9 @@
             <div>
                 <div class="top mt-4 px-4">
                     <div class="flex items-center">
-                        <div class="text-xl font-bold flex-1">Me</div>
+                        <div class="text-xl font-bold flex-1" @click="clickMe">
+                            Me
+                        </div>
                         <div class="flex p-2">
                             <IonIcon
                                 :icon="settingsOutline"
@@ -17,6 +19,7 @@
                         <img
                             :src="user?.avatar || IconAvatar"
                             class="w-[64px] h-[64px] rounded-full object-cover"
+                            @click="profile"
                         />
                         <div class="ml-4 flex-1">
                             <div class="text-lg">{{ user?.username }}</div>
@@ -43,26 +46,29 @@
                     >
                         <div class="flex-1 leading-none">
                             <div
-                                class="leading-none font-bold text-white text-opacity-90"
+                                class="leading-none text-white text-opacity-90"
                             >
-                                SHARE WITH YOUR FRIENDS
+                                Share with Friends
                             </div>
                             <div
-                                class="mt-1 leading-none font-bold text-white text-opacity-90"
+                                class="mt-1 leading-none text-white text-opacity-90"
                             >
-                                GET FREE WATCHING
+                                Get Free Watching
                             </div>
                         </div>
                         <div
                             class="bg-white text-prim font-bold px-3 py-1 rounded-full shadow"
                             @click="showInviteModal = true"
                         >
-                            SHARE
+                            Share
                         </div>
                     </div>
-                    <div class="mt-8 flex items-center text-xl h-16">
-                        <IonIcon class="text-neutral-100" :icon="timeOutline" />
-                        <div class="ml-2 text-base flex-1">Watch History</div>
+                    <div class="mt-8 flex items-center h-16">
+                        <IonIcon
+                            class="text-neutral-100 text-xl"
+                            :icon="timeOutline"
+                        />
+                        <div class="ml-2 flex-1">Watch History</div>
                         <IonIcon
                             class="text-neutral-500"
                             :icon="chevronForwardOutline"
@@ -77,12 +83,15 @@
                             class="mr-4"
                         />
                     </div>
-                    <div class="flex items-center text-xl h-16">
+                    <div
+                        class="flex items-center h-16"
+                        @click="router.push('/feedback')"
+                    >
                         <IonIcon
-                            class="text-neutral-100"
+                            class="text-neutral-100 text-xl"
                             :icon="chatboxOutline"
                         />
-                        <div class="ml-2 text-base flex-1">Feedback</div>
+                        <div class="ml-2 flex-1">Feedback</div>
                         <IonIcon
                             class="text-neutral-500"
                             :icon="chevronForwardOutline"
@@ -96,7 +105,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
+import { reactive, ref } from "vue";
 import {
     IonPage,
     IonContent,
@@ -122,6 +131,8 @@ import bgInviteModal from "@/assets/bg_invite_modal.png";
 import SeriesItem from "@/components/SeriesItem.vue";
 import IconAvatar from "@/assets/icon_avatar.png";
 import ShareModal from "@/components/ShareModal.vue";
+import { useDebounceFn } from "@vueuse/core";
+import { showConsole } from "@/plugins/eruda";
 
 const router = useIonRouter();
 const { user } = storeToRefs(useUserStore());
@@ -136,6 +147,27 @@ onIonViewDidEnter(() => {
 });
 
 const showInviteModal = ref(false);
+
+function profile() {
+    if (user.value && !user.value.visitor) {
+        router.push("/profile");
+    } else {
+        router.push("/login");
+    }
+}
+
+const count = reactive({ value: 0 });
+function clickMe() {
+    count.value++;
+    resetCount();
+    if (count.value > 10) {
+        showConsole(true);
+    }
+}
+
+const resetCount = useDebounceFn(() => {
+    count.value = 0;
+}, 1000);
 </script>
 <style lang="less" scoped>
 .top {

+ 1 - 6
src/views/MyListTab.vue

@@ -5,12 +5,7 @@
                 <ion-title>My List</ion-title>
             </ion-toolbar>
         </ion-header>
-        <ion-content :fullscreen="true">
-            <ion-header collapse="condense">
-                <ion-toolbar>
-                    <ion-title size="large">My List</ion-title>
-                </ion-toolbar>
-            </ion-header>
+        <ion-content>
             <div class="p-4">
                 <div
                     class="grid grid-cols-2 xs:grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-7 2xl:grid-cols-8 gap-4"

+ 42 - 6
src/views/SeriesView.vue

@@ -8,7 +8,7 @@
                     class="w-full h-full"
                     virtual
                     direction="vertical"
-                    :initialSlide="0"
+                    :initialSlide="initialSlide"
                     :slides-per-view="1"
                     :space-between="0"
                     :pagination="true"
@@ -35,11 +35,13 @@
                             :episode="item"
                             :episodes="episodes"
                             :saved="saved"
+                            :ref="(el) => (playViews[item.id] = el)"
                             @save="save"
                             @choose-episode="onChooseEpisode"
                             @ended="next"
                             @pay="showPayModal = true"
                             @share="showShareModal = true"
+                            @progress="saveHistory"
                         />
                     </swiper-slide>
                 </VueSwiper>
@@ -165,10 +167,10 @@ import {
 } from "swiper/modules";
 import PlayView from "@/components/PlayView.vue";
 import { nextTick, onMounted, reactive, ref } from "vue";
-import { useElementBounding } from "@vueuse/core";
+import { useElementBounding, useLocalStorage } from "@vueuse/core";
 import { useRoute } from "vue-router";
 import http from "@/plugins/http";
-import { close, chevronBack } from "ionicons/icons";
+import { close, chevronBack, key } from "ionicons/icons";
 import toast from "@/plugins/toast";
 import { useUserStore } from "@/store/user";
 import { storeToRefs } from "pinia";
@@ -179,7 +181,7 @@ const { user } = storeToRefs(useUserStore());
 const el = ref<HTMLElement | null>(null);
 const { x, y, top, right, bottom, left, width, height } =
     useElementBounding(el);
-
+const initialSlide = ref(0);
 const swiper = ref<Swiper | null>(null);
 const onSwiper = (sw: Swiper) => {
     window.swiper = swiper.value = sw;
@@ -188,10 +190,11 @@ const activeSlide = ref(0);
 
 const route = useRoute();
 const router = useIonRouter();
-const seriesId = route.params.id;
+const seriesId = route.params.id as string;
 const series = ref<any>(null);
 const episodes = ref<any[]>([]);
-
+const historyStore = useLocalStorage<any>("playHistories", {});
+const playViews = ref<{ [key: string | number]: any }>({});
 onMounted(() => {
     http.get(`/series/${seriesId}`).then((res) => {
         series.value = res;
@@ -201,8 +204,29 @@ onMounted(() => {
             pageSize: 1000,
         }).then((res) => {
             episodes.value = res.data;
+            const history = historyStore.value[seriesId];
+            if (history) {
+                console.log("found history", historyStore.value[seriesId]);
+                const index = episodes.value.findIndex(
+                    (e) => e.id === history.episodeId
+                );
+                if (index !== -1) {
+                    initialSlide.value = index;
+                }
+            }
             nextTick(() => {
                 swiper.value?.update();
+                if (initialSlide.value > 0) {
+                    console.log("slide to", initialSlide.value);
+                    swiper.value?.slideTo(initialSlide.value, 0);
+                }
+                if (history) {
+                    const playView =
+                        playViews.value[episodes.value[initialSlide.value].id];
+                    if (playView) {
+                        playView.seek(history.duration);
+                    }
+                }
             });
         });
     });
@@ -297,6 +321,18 @@ function onClickPay() {
 }
 
 const showShareModal = ref(false);
+
+function saveHistory(e: {
+    seriesId: number;
+    episodeId: number;
+    duration: number;
+}) {
+    http.post("/playHistories", e);
+    historyStore.value[e.seriesId + ""] = {
+        episodeId: e.episodeId,
+        duration: e.duration,
+    };
+}
 </script>
 <style lang="less" scoped>
 .pay-modal {

+ 13 - 2
src/views/SettingsView.vue

@@ -11,10 +11,15 @@
         <IonContent>
             <div class="mt-8 px-4 rounded-md">
                 <IonItemGroup class="bg-neutral-900 rounded-md">
-                    <ion-item detail button @click="router.push('/profile')">
+                    <ion-item
+                        v-if="user && !user.visitor"
+                        detail
+                        button
+                        @click="router.push('/profile')"
+                    >
                         <ion-label> Profile </ion-label>
                     </ion-item>
-                    <ion-item detail button>
+                    <ion-item detail button @click="privacy">
                         <ion-label> Privacy and Terms </ion-label>
                     </ion-item>
                 </IonItemGroup>
@@ -56,6 +61,8 @@ import {
 import { useUserStore } from "@/store/user";
 import { storeToRefs } from "pinia";
 import http from "@/plugins/http";
+import { Browser } from "@capacitor/browser";
+
 const userStore = useUserStore();
 const { setUser } = userStore;
 const { user } = storeToRefs(userStore);
@@ -83,6 +90,10 @@ const actionSheetButtons = [
         },
     },
 ];
+
+async function privacy() {
+    await Browser.open({ url: http.resolve("/static/privacy.html") });
+}
 </script>
 <style lang="less" scoped>
 ion-item {

+ 7 - 3
src/views/TabsPage.vue

@@ -30,7 +30,7 @@
                         v-if="activeTab == 'myList'"
                     />
                     <ion-icon aria-hidden="true" :icon="IconTabList" v-else />
-                    <ion-label>My List</ion-label>
+                    <span>My List</span>
                 </ion-tab-button>
 
                 <ion-tab-button tab="me" href="/tabs/me">
@@ -73,8 +73,12 @@ const tabChange = (tabInfo: any) => {
     activeTab.value = tabInfo.tab;
 };
 </script>
-<style scoped>
+<style lang="less" scoped>
 ion-tab-button {
-    --color-selected: var(--ion-color-tertiary-shade);
+    --color: #959595;
+    --color-selected: #959595;
+}
+ion-tab-button.tab-selected {
+    --color-selected: #ff136a;
 }
 </style>

+ 1 - 1
tailwind.config.js

@@ -3,7 +3,7 @@ export default {
     content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
     theme: {
         screens: {
-            xs: "375px",
+            xs: "360px",
             sm: "640px",
             md: "768px",
             lg: "1024px",