feat: blocca orientamento in portrait su APK e browser

- Dockerfile: aggiunge android:screenOrientation="portrait" all'activity
  in AndroidManifest.xml per bloccare il portrait nativamente sull'APK
- App.vue: fixOrientation() rileva il landscape tramite dimensioni viewport
  e applica un counter-rotate CSS in modo che l'app rimanga visivamente
  in portrait anche da browser mobile (dev server)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-12 18:41:22 +02:00
parent 3bd2b04a06
commit 47f4bcba28
2 changed files with 48 additions and 1 deletions
+4
View File
@@ -56,6 +56,10 @@ RUN npx cap add android
RUN sed -i 's|</manifest>| <uses-permission android:name="android.permission.CAMERA" />\n</manifest>|' \
android/app/src/main/AndroidManifest.xml
# ── Orientamento bloccato in portrait ────────────────────────────────────────
RUN sed -i 's/android:exported="true"/android:exported="true"\n android:screenOrientation="portrait"/' \
android/app/src/main/AndroidManifest.xml
# ── Versione da package.json → android/app/build.gradle ──────────────────────
RUN node -e "\
const v = require('./package.json').version; \
+44 -1
View File
@@ -16,11 +16,12 @@
<InfoPanel v-model="showInfo" @open-docs="showDocs = true" />
<DocsPanel v-model="showDocs" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted, onUnmounted } from 'vue'
import BottomNav from './components/BottomNav.vue'
import InfoPanel from './components/InfoPanel.vue'
import DocsPanel from './components/DocsPanel.vue'
@@ -31,6 +32,47 @@ import ShoppingList from './pages/ShoppingList.vue'
const page = ref('meal')
const showInfo = ref(false)
const showDocs = ref(false)
function fixOrientation() {
const isLandscape = window.innerWidth > window.innerHeight
// screen.orientation.angle potrebbe non essere ancora aggiornato o non disponibile:
// fallback basato su dimensioni finestra
const angle = screen.orientation?.angle ?? (isLandscape ? 90 : 0)
const root = document.getElementById('app-root')
if (!root) return
if (isLandscape) {
const w = window.innerWidth
const h = window.innerHeight
root.style.cssText = `
position: fixed;
width: ${h}px;
height: ${w}px;
top: ${(h - w) / 2}px;
left: ${(w - h) / 2}px;
transform: rotate(${angle === 90 ? -90 : 90}deg);
transform-origin: center center;
`
} else {
root.style.cssText = ''
}
}
// orientationchange si triggera prima che angle/dimensioni siano aggiornati:
// aspettiamo un tick
function onOrientationChange() {
setTimeout(fixOrientation, 50)
}
onMounted(() => {
fixOrientation()
window.addEventListener('orientationchange', onOrientationChange)
window.addEventListener('resize', fixOrientation)
})
onUnmounted(() => {
window.removeEventListener('orientationchange', onOrientationChange)
window.removeEventListener('resize', fixOrientation)
})
</script>
<style scoped>
@@ -67,4 +109,5 @@ const showDocs = ref(false)
box-shadow: var(--shadow-md);
opacity: 1;
}
</style>