Skip to content

Commit

Permalink
Implement ads in desktop app
Browse files Browse the repository at this point in the history
  • Loading branch information
Geometrically committed Aug 28, 2024
1 parent bf16d36 commit 79a180c
Show file tree
Hide file tree
Showing 23 changed files with 404 additions and 41 deletions.
54 changes: 54 additions & 0 deletions apps/app-frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,60 @@
<title>Modrinth App</title>

<link rel="stylesheet" href="/src/assets/stylesheets/global.scss" />
<script src="https://modrinth.com/inmobi.js" async></script>
<style>
#qc-cmp2-ui {
background: var(--color-raised-bg);
border-radius: var(--radius-lg);
color: var(--color-base);
}

#qc-cmp2-ui::before {
background: var(--color-raised-bg);
}

#qc-cmp2-ui::after {
background: var(--color-raised-bg);
}

#qc-cmp2-ui button[mode="primary"] {
background: var(--color-brand);
color: var(--color-accent-contrast);
border-radius: var(--radius-lg);
border: none;
}

#qc-cmp2-ui button[mode="secondary"] {
background: var(--color-button-bg);
color: var(--color-base);
border-radius: var(--radius-lg);
border: none;
}

#qc-cmp2-ui button[mode="link"] {
color: var(--color-link);
}

#qc-cmp2-ui h2 {
color: var(--color-contrast);
font-size: 1.5rem;
}

#qc-cmp2-ui div,
#qc-cmp2-ui li,
#qc-cmp2-ui strong,
#qc-cmp2-ui p,
#qc-cmp2-ui .qc-cmp2-list-item-title,
#qc-cmp2-ui .qc-cmp2-expandable-info {
color: var(--color-base);
font-family: var(--font-standard);
}

#qc-cmp2-ui .qc-cmp2-toggle[aria-checked="true"] {
background-color: var(--color-brand);
border: 1px solid var(--color-brand);
}
</style>
</head>

<body>
Expand Down
85 changes: 82 additions & 3 deletions apps/app-frontend/src/components/ui/PromotionWrapper.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Promotion } from '@modrinth/ui'
import { ref, onMounted, onUnmounted } from 'vue'
import { get as getCreds } from '@/helpers/mr_auth.js'
import { handleError } from '@/store/notifications.js'
import { get_user } from '@/helpers/cache.js'
import { ChevronRightIcon } from '@modrinth/assets'
import { init_ads_window } from '@/helpers/ads.js'
const showAd = ref(true)
defineExpose({
scroll() {
updateAdPosition()
},
})
const creds = await getCreds().catch(handleError)
if (creds && creds.user_id) {
const user = await get_user(creds.user_id).catch(handleError)
Expand All @@ -16,8 +23,80 @@ if (creds && creds.user_id) {
showAd.value = false
}
}
const adsWrapper = ref(null)
let resizeObserver
let scrollHandler
let intersectionObserver
let mutationObserver
onMounted(() => {
if (showAd.value) {
updateAdPosition()
resizeObserver = new ResizeObserver(updateAdPosition)
resizeObserver.observe(adsWrapper.value)
intersectionObserver = new IntersectionObserver(updateAdPosition)
intersectionObserver.observe(adsWrapper.value)
mutationObserver = new MutationObserver(updateAdPosition)
mutationObserver.observe(adsWrapper.value, { attributes: true, childList: true, subtree: true })
// Add scroll event listener
scrollHandler = () => {
requestAnimationFrame(updateAdPosition)
}
window.addEventListener('scroll', scrollHandler, { passive: true })
}
})
function updateAdPosition() {
if (adsWrapper.value) {
const rect = adsWrapper.value.getBoundingClientRect()
init_ads_window(
rect.left + window.scrollX,
rect.top + window.scrollY,
rect.right - rect.left,
rect.bottom - rect.top,
)
}
}
onUnmounted(() => {
if (resizeObserver) {
resizeObserver.disconnect()
}
if (intersectionObserver) {
intersectionObserver.disconnect()
}
if (mutationObserver) {
mutationObserver.disconnect()
}
if (scrollHandler) {
window.removeEventListener('scroll', scrollHandler)
}
})
</script>

<template>
<Promotion v-if="showAd" :external="false" query-param="?r=launcher" />
<div
v-if="showAd"
ref="adsWrapper"
class="ad-parent relative mb-3 flex w-full justify-center rounded-2xl bg-bg-raised"
>
<div class="flex max-h-[250px] min-h-[250px] min-w-[300px] max-w-[300px] flex-col gap-4 p-6">
<p class="m-0 text-2xl font-bold text-contrast">90% of ad revenue goes to creators</p>
<a
href="https://modrinth.com/plus"
class="mt-auto items-center gap-1 text-purple hover:underline"
>
<span>
Support creators and Modrinth ad-free with
<span class="font-bold">Modrinth+</span>
</span>
<ChevronRightIcon class="relative top-[3px] h-5 w-5" />
</a>
</div>
</div>
</template>
9 changes: 9 additions & 0 deletions apps/app-frontend/src/helpers/ads.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { invoke } from '@tauri-apps/api/core'

export async function init_ads_window(x, y, width, height) {
return await invoke('plugin:ads|init_ads_window', { x, y, width, height })
}

export async function hide_ads_window() {
return await invoke('plugin:ads|hide_ads_window')
}
11 changes: 5 additions & 6 deletions apps/app-frontend/src/pages/Browse.vue
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,8 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu

<template>
<div ref="searchWrapper" class="search-container">
<aside class="filter-panel">
<aside class="filter-panel" @scroll="$refs.promo.scroll()">
<PromotionWrapper ref="promo" />
<Card v-if="instanceContext" class="small-instance">
<router-link :to="`/instance/${encodeURIComponent(instanceContext.path)}`" class="instance">
<Avatar
Expand Down Expand Up @@ -675,8 +676,7 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu
</Card>
</aside>
<div class="search">
<PromotionWrapper class="mt-4" />
<Card class="project-type-container">
<Card class="project-type-container mt-4">
<NavRow :links="selectableProjectTypes" />
</Card>
<Card class="search-panel-container">
Expand Down Expand Up @@ -878,7 +878,6 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu
.filter-panel {
position: fixed;
width: 20rem;
padding: 1rem 0.5rem 1rem 1rem;
display: flex;
flex-direction: column;
Expand All @@ -903,8 +902,8 @@ const isModProject = computed(() => ['modpack', 'mod'].includes(projectType.valu
}
.search {
margin: 0 1rem 0.5rem 20.5rem;
width: calc(100% - 20.5rem);
margin: 0 1rem 0.5rem calc(300px + 2.5rem);
width: calc(100% - calc(300px + 2.5rem));
.offline {
margin: 1rem;
Expand Down
7 changes: 6 additions & 1 deletion apps/app-frontend/src/pages/Index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { ref, onUnmounted, computed } from 'vue'
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import RowDisplay from '@/components/RowDisplay.vue'
import { list } from '@/helpers/profile.js'
Expand All @@ -8,6 +8,11 @@ import { useBreadcrumbs } from '@/store/breadcrumbs'
import { handleError } from '@/store/notifications.js'
import dayjs from 'dayjs'
import { get_search_results } from '@/helpers/cache.js'
import { hide_ads_window } from '@/helpers/ads.js'
onMounted(() => {
hide_ads_window()
})
const featuredModpacks = ref({})
const featuredMods = ref({})
Expand Down
7 changes: 6 additions & 1 deletion apps/app-frontend/src/pages/Library.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { onUnmounted, ref, shallowRef } from 'vue'
import { onMounted, onUnmounted, ref, shallowRef } from 'vue'
import GridDisplay from '@/components/GridDisplay.vue'
import { list } from '@/helpers/profile.js'
import { useRoute } from 'vue-router'
Expand All @@ -10,6 +10,11 @@ import { Button } from '@modrinth/ui'
import { PlusIcon } from '@modrinth/assets'
import InstanceCreationModal from '@/components/ui/InstanceCreationModal.vue'
import { NewInstanceImage } from '@/assets/icons'
import { hide_ads_window } from '@/helpers/ads.js'
onMounted(() => {
hide_ads_window()
})
const route = useRoute()
const breadcrumbs = useBreadcrumbs()
Expand Down
7 changes: 6 additions & 1 deletion apps/app-frontend/src/pages/Settings.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { ref, watch } from 'vue'
import { ref, watch, onMounted } from 'vue'
import { LogOutIcon, LogInIcon, BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
import { Card, Slider, DropdownSelect, Toggle, ConfirmModal, Button } from '@modrinth/ui'
import { handleError, useTheming } from '@/store/state'
Expand All @@ -13,6 +13,11 @@ import { open } from '@tauri-apps/plugin-dialog'
import { getOS } from '@/helpers/utils.js'
import { getVersion } from '@tauri-apps/api/app'
import { get_user, purge_cache_types } from '@/helpers/cache.js'
import { hide_ads_window } from '@/helpers/ads.js'
onMounted(() => {
hide_ads_window()
})
const pageOptions = ['Home', 'Library']
Expand Down
25 changes: 11 additions & 14 deletions apps/app-frontend/src/pages/instance/Index.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div class="instance-container">
<div class="side-cards">
<div class="side-cards pb-4" @scroll="$refs.promo.scroll()">
<Card class="instance-card" @contextmenu.prevent.stop="handleRightClick">
<Avatar size="lg" :src="instance.icon_path ? convertFileSrc(instance.icon_path) : null" />
<Avatar size="md" :src="instance.icon_path ? convertFileSrc(instance.icon_path) : null" />
<div class="instance-info">
<h2 class="name">{{ instance.name }}</h2>
<span class="metadata"> {{ instance.loader }} {{ instance.game_version }} </span>
Expand Down Expand Up @@ -61,9 +61,9 @@
</RouterLink>
</div>
</Card>
<PromotionWrapper ref="promo" class="mt-4" />
</div>
<div class="content">
<PromotionWrapper />
<RouterView v-slot="{ Component }">
<template v-if="Component">
<Suspense @pending="loadingBar.startLoading()" @resolve="loadingBar.stopLoading()">
Expand Down Expand Up @@ -311,7 +311,6 @@ onUnmounted(() => {
display: flex;
flex-direction: column;
gap: 1rem;
width: 17rem;
}
Button {
Expand All @@ -325,12 +324,13 @@ Button {
}
.side-cards {
position: absolute;
position: fixed;
width: 300px;
display: flex;
flex-direction: column;
padding: 1rem;
min-height: calc(100% - 3.25rem);
max-height: calc(100% - 3.25rem);
min-height: calc(100vh - 3.25rem);
max-height: calc(100vh - 3.25rem);
overflow-y: auto;
-ms-overflow-style: none;
scrollbar-width: none;
Expand Down Expand Up @@ -374,10 +374,7 @@ Button {
overflow: auto;
gap: 1rem;
min-height: 100%;
}
.content {
margin-left: 19rem;
padding: 1rem;
}
.instance-info {
Expand Down Expand Up @@ -451,10 +448,10 @@ Button {
}
.content {
width: 100%;
margin: 0 1rem 0.5rem 20rem;
width: calc(100% - 20rem);
display: flex;
flex-direction: column;
padding: 1rem 1rem 0 0;
overflow: auto;
}
Expand Down
13 changes: 7 additions & 6 deletions apps/app-frontend/src/pages/project/Index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div class="root-container">
<div v-if="data" class="project-sidebar">
<div v-if="data" class="project-sidebar" @scroll="$refs.promo.scroll()">
<Card v-if="instance" class="small-instance">
<router-link class="instance" :to="`/instance/${encodeURIComponent(instance.path)}`">
<Avatar
Expand All @@ -20,7 +20,7 @@
</router-link>
</Card>
<Card class="sidebar-card" @contextmenu.prevent.stop="handleRightClick">
<Avatar size="lg" :src="data.icon_url" />
<Avatar size="md" :src="data.icon_url" />
<div class="instance-info">
<h2 class="name">{{ data.title }}</h2>
{{ data.description }}
Expand Down Expand Up @@ -61,7 +61,9 @@
Site
</a>
</div>
<hr class="card-divider" />
</Card>
<PromotionWrapper ref="promo" />
<Card class="sidebar-card">
<div class="stats">
<div class="stat">
<DownloadIcon aria-hidden="true" />
Expand Down Expand Up @@ -163,7 +165,6 @@
</Card>
</div>
<div v-if="data" class="content-container">
<PromotionWrapper />
<Card class="tabs">
<NavRow
v-if="data.gallery.length > 0"
Expand Down Expand Up @@ -377,7 +378,7 @@ const handleOptionsClick = (args) => {
.project-sidebar {
position: fixed;
width: 20rem;
width: calc(300px + 1.5rem);
min-height: calc(100vh - 3.25rem);
height: fit-content;
max-height: calc(100vh - 3.25rem);
Expand All @@ -403,7 +404,7 @@ const handleOptionsClick = (args) => {
flex-direction: column;
width: 100%;
padding: 1rem;
margin-left: 19.5rem;
margin-left: calc(300px + 1rem);
}
.button-group {
Expand Down
Loading

0 comments on commit 79a180c

Please sign in to comment.