Compare commits

..

14 Commits

Author SHA1 Message Date
Jai A
356a06e694 add signal for app vs web 2024-10-15 23:47:51 -07:00
Geometrically
fce516a76f Remove ads muting (#2511) 2024-10-15 23:43:49 -07:00
Jai A
42ade0fbd1 make script non-async 2024-10-15 10:56:35 -07:00
Jai A
ba07f5dad4 Add clean.io direct 2024-10-15 10:52:00 -07:00
Jai A
cc89e0f3f1 remove ad cookie (main) 2024-10-14 23:49:27 -07:00
Jai A
0e14d3f9c1 update ads.txt 2024-10-14 23:47:42 -07:00
Norbiros
6716e2277d fix(theseus): Files drag & drop (#2499)
Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
2024-10-12 13:27:07 -07:00
Mysticdrew
f986dc5d11 Remove extra "not" (#2506)
Signed-off-by: Mysticdrew <drewhaas@gmail.com>
2024-10-10 15:27:43 -07:00
Geometrically
570a4096f9 Update billing with backend changes (#2505) 2024-10-09 21:11:49 -07:00
Jai A
d302795512 Fix ad init not working on no tauri invoke 2024-10-09 14:04:33 -07:00
Jai A
115acce80c Add hashing to ads 2024-10-09 13:54:35 -07:00
Geometrically
a8731b0ca2 Fix unfollowing projects (#2496) 2024-10-08 15:19:46 -07:00
nekk
fd596bf418 type in ErrorModal.vue (#2492)
Signed-off-by: nekk <108535017+iam-nekk@users.noreply.github.com>
2024-10-06 21:11:39 +00:00
Geometrically
ef7cfffeb6 Add support for Optima (#2489) 2024-10-04 13:35:39 -07:00
16 changed files with 283 additions and 153 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "@modrinth/app-frontend",
"private": true,
"version": "0.8.8",
"version": "0.8.9",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -230,7 +230,7 @@ async function repairInstance() {
</p>
<p>You may be able to fix it through one of the following ways:</p>
<ul>
<li>Ennsuring you are connected to the internet, then try restarting the app.</li>
<li>Ensuring you are connected to the internet, then try restarting the app.</li>
<li>Redownloading the app.</li>
</ul>
</template>

View File

@@ -218,7 +218,6 @@ import { get_game_versions, get_loader_versions } from '@/helpers/metadata'
import { handleError } from '@/store/notifications.js'
import Multiselect from 'vue-multiselect'
import { trackEvent } from '@/helpers/analytics'
import { listen } from '@tauri-apps/api/event'
import { install_from_file } from '@/helpers/pack.js'
import {
get_default_launcher_path,
@@ -226,6 +225,7 @@ import {
import_instance,
} from '@/helpers/import.js'
import ProgressBar from '@/components/ui/ProgressBar.vue'
import { getCurrentWebview } from '@tauri-apps/api/webview'
const profile_name = ref('')
const game_version = ref('')
@@ -255,13 +255,15 @@ defineExpose({
isShowing.value = true
modal.value.show()
unlistener.value = await listen('tauri://file-drop', async (event) => {
unlistener.value = await getCurrentWebview().onDragDropEvent(async (event) => {
// Only if modal is showing
if (!isShowing.value) return
if (event.payload.type !== 'drop') return
if (creationType.value !== 'from file') return
hide()
if (event.payload && event.payload.length > 0 && event.payload[0].endsWith('.mrpack')) {
await install_from_file(event.payload[0]).catch(handleError)
const { paths } = event.payload
if (paths && paths.length > 0 && paths[0].endsWith('.mrpack')) {
await install_from_file(paths[0]).catch(handleError)
trackEvent('InstanceCreate', {
source: 'CreationModalFileDrop',
})

View File

@@ -378,7 +378,6 @@ import {
} from '@/helpers/profile.js'
import { handleError } from '@/store/notifications.js'
import { trackEvent } from '@/helpers/analytics'
import { listen } from '@tauri-apps/api/event'
import { highlightModInProfile } from '@/helpers/utils.js'
import { MenuIcon, ToggleIcon, TextInputIcon, AddProjectImage, PackageIcon } from '@/assets/icons'
import ExportModal from '@/components/ui/ExportModal.vue'
@@ -393,6 +392,7 @@ import {
import { profile_listener } from '@/helpers/events.js'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import ShareModalWrapper from '@/components/ui/modal/ShareModalWrapper.vue'
import { getCurrentWebview } from '@tauri-apps/api/webview'
const props = defineProps({
instance: {
@@ -879,8 +879,10 @@ async function refreshProjects() {
refreshingProjects.value = false
}
const unlisten = await listen('tauri://file-drop', async (event) => {
for (const file of event.payload) {
const unlisten = await getCurrentWebview().onDragDropEvent(async (event) => {
if (event.payload.type !== 'drop') return
for (const file of event.payload.paths) {
if (file.endsWith('.mrpack')) continue
await add_project_from_path(props.instance.path, file).catch(handleError)
}

View File

@@ -1,6 +1,6 @@
[package]
name = "theseus_gui"
version = "0.8.8"
version = "0.8.9"
description = "The Modrinth App is a desktop application for managing your Minecraft mods"
license = "GPL-3.0-only"
repository = "https://github.com/modrinth/code/apps/app/"

View File

@@ -21,86 +21,3 @@ document.addEventListener(
window.open = (url, target, features) => {
window.top.postMessage({ modrinthOpenUrl: url }, 'https://modrinth.com')
}
function muteAudioContext() {
if (window.AudioContext || window.webkitAudioContext) {
const AudioContext = window.AudioContext || window.webkitAudioContext
const originalCreateMediaElementSource = AudioContext.prototype.createMediaElementSource
const originalCreateMediaStreamSource = AudioContext.prototype.createMediaStreamSource
const originalCreateMediaStreamTrackSource = AudioContext.prototype.createMediaStreamTrackSource
const originalCreateBufferSource = AudioContext.prototype.createBufferSource
const originalCreateOscillator = AudioContext.prototype.createOscillator
AudioContext.prototype.createGain = function () {
const gain = originalCreateGain.call(this)
gain.gain.value = 0
return gain
}
AudioContext.prototype.createMediaElementSource = function (mediaElement) {
const source = originalCreateMediaElementSource.call(this, mediaElement)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamSource = function (mediaStream) {
const source = originalCreateMediaStreamSource.call(this, mediaStream)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createMediaStreamTrackSource = function (mediaStreamTrack) {
const source = originalCreateMediaStreamTrackSource.call(this, mediaStreamTrack)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createBufferSource = function () {
const source = originalCreateBufferSource.call(this)
source.connect(this.createGain())
return source
}
AudioContext.prototype.createOscillator = function () {
const oscillator = originalCreateOscillator.call(this)
oscillator.connect(this.createGain())
return oscillator
}
}
}
function muteVideo(mediaElement) {
let count = Number(mediaElement.getAttribute('data-modrinth-muted-count') ?? 0)
if (!mediaElement.muted || mediaElement.volume !== 0) {
mediaElement.muted = true
mediaElement.volume = 0
mediaElement.setAttribute('data-modrinth-muted-count', count + 1)
}
if (count > 5) {
// Video is detected as malicious, so it is removed from the page
mediaElement.remove()
}
}
function muteVideos() {
document.querySelectorAll('video, audio').forEach(function (mediaElement) {
muteVideo(mediaElement)
if (!mediaElement.hasAttribute('data-modrinth-muted')) {
mediaElement.addEventListener('volumechange', () => muteVideo(mediaElement))
mediaElement.setAttribute('data-modrinth-muted', 'true')
}
})
}
document.addEventListener('DOMContentLoaded', () => {
muteVideos()
muteAudioContext()
const observer = new MutationObserver(muteVideos)
observer.observe(document.body, { childList: true, subtree: true })
})

View File

@@ -49,7 +49,7 @@
]
},
"productName": "Modrinth App",
"version": "0.8.8",
"version": "0.8.9",
"mainBinaryName": "Modrinth App",
"identifier": "ModrinthApp",
"plugins": {

View File

@@ -23,9 +23,19 @@ import { ChevronRightIcon } from "@modrinth/assets";
useHead({
script: [
{
// Clean.io
src: "https://cadmus.script.ac/d14pdm1b7fi5kh/script.js",
},
{
// Aditude
src: "https://dn0qt3r0xannq.cloudfront.net/modrinth-7JfmkEIXEp/modrinth-longform/prebid-load.js",
async: true,
},
{
// Optima
src: "https://bservr.com/o.js?uid=8118d1fdb2e0d6f32180bd27",
async: true,
},
{
src: "/inmobi.js",
async: true,
@@ -47,6 +57,9 @@ onMounted(() => {
{
divId: "modrinth-rail-1",
baseDivId: "pb-slot-square-2",
targeting: {
location: "web",
},
},
]);
});

View File

@@ -612,7 +612,7 @@ const visibility = ref(collection.value.status);
const removeProjects = ref([]);
async function unfollowProject(project) {
await userUnfollowProject(project);
await userFollowProject(project);
projects.value = projects.value.filter((x) => x.id !== project.id);
}

View File

@@ -81,9 +81,9 @@
<h3 id="pending">What does "pending" revenue mean in my dashboard?</h3>
<p>
Modrinth receives ad revenue from our ad providers on a NET 60 day basis. Due to this, not all
revenue is not immediately available to withdraw. We pay creators as soon as we receive the
money from our ad providers, which is 60 days after the last day of each month. This table
outlines some example dates of how NET 60 payments are made:
revenue is immediately available to withdraw. We pay creators as soon as we receive the money
from our ad providers, which is 60 days after the last day of each month. This table outlines
some example dates of how NET 60 payments are made:
</p>
<table>
<thead>

View File

@@ -17,33 +17,24 @@
<span class="font-bold text-primary">
<template v-if="charge.product.metadata.type === 'midas'"> Modrinth Plus </template>
<template v-else> Unknown product </template>
<template v-if="charge.metadata.modrinth_subscription_interval">
{{ charge.metadata.modrinth_subscription_interval }}
<template v-if="charge.subscription_interval">
{{ charge.subscription_interval }}
</template>
</span>
<span>{{ formatPrice(charge.amount, charge.currency) }}</span>
<span>{{ formatPrice(charge.amount, charge.currency_code) }}</span>
</div>
<div class="flex items-center gap-1">
<Badge :color="charge.status === 'succeeded' ? 'green' : 'red'" :type="charge.status" />
{{ $dayjs.unix(charge.created).format("YYYY-MM-DD") }}
{{ $dayjs(charge.due).format("YYYY-MM-DD") }}
</div>
</div>
<a
v-if="charge.receipt_url"
class="iconified-button raised-button"
:href="charge.receipt_url"
>
<ReceiptTextIcon />
View receipt
</a>
</div>
</section>
</div>
</template>
<script setup>
import { ReceiptTextIcon } from "@modrinth/assets";
import { Breadcrumbs, Badge } from "@modrinth/ui";
import { products } from "~/generated/state.json";
@@ -58,15 +49,17 @@ const { data: charges } = await useAsyncData(
() => useBaseFetch("billing/payments", { internal: true }),
{
transform: (charges) => {
return charges.map((charge) => {
const product = products.find((product) =>
product.prices.some((price) => price.id === charge.metadata.modrinth_price_id),
);
return charges
.filter((charge) => charge.status !== "open" && charge.status !== "cancelled")
.map((charge) => {
const product = products.find((product) =>
product.prices.some((price) => price.id === charge.price_id),
);
charge.product = product;
charge.product = product;
return charge;
});
return charge;
});
},
},
);

View File

@@ -8,22 +8,20 @@
:title="formatMessage(cancelModalMessages.title)"
:description="formatMessage(cancelModalMessages.description)"
:proceed-label="formatMessage(cancelModalMessages.action)"
@proceed="cancelSubscription(cancelSubscriptionId)"
@proceed="cancelSubscription(cancelSubscriptionId, true)"
/>
<div class="flex flex-wrap justify-between gap-4">
<div class="flex flex-col gap-4">
<template v-if="midasSubscription">
<span v-if="midasSubscription.status === 'active'">
You're currently subscribed to:
</span>
<span v-else-if="midasSubscription.status === 'payment-processing'" class="text-orange">
<template v-if="midasCharge">
<span v-if="midasCharge.status === 'open'"> You're currently subscribed to: </span>
<span v-else-if="midasCharge.status === 'processing'" class="text-orange">
Your payment is being processed. Perks will activate once payment is complete.
</span>
<span v-else-if="midasSubscription.status === 'cancelled'">
<span v-else-if="midasCharge.status === 'cancelled'">
You've cancelled your subscription. <br />
You will retain your perks until the end of the current billing cycle.
</span>
<span v-else-if="midasSubscription.status === 'payment-failed'" class="text-red">
<span v-else-if="midasCharge.status === 'failed'" class="text-red">
Your subscription payment failed. Please update your payment method.
</span>
</template>
@@ -49,34 +47,31 @@
<div class="flex w-full flex-wrap justify-between gap-4 xl:w-auto xl:flex-col">
<div class="flex flex-col gap-1 xl:ml-auto xl:text-right">
<span class="text-2xl font-bold text-dark">
<template v-if="midasSubscription">
<template v-if="midasCharge">
{{
formatPrice(
vintl.locale,
midasSubscriptionPrice.prices.intervals[midasSubscription.interval],
midasSubscriptionPrice.prices.intervals[midasCharge.subscription_interval],
midasSubscriptionPrice.currency_code,
)
}}
/
{{ midasSubscription.interval }}
{{ midasCharge.subscription_interval }}
</template>
<template v-else>
{{ formatPrice(vintl.locale, price.prices.intervals.monthly, price.currency_code) }}
/ month
</template>
</span>
<template v-if="midasSubscription">
<template v-if="midasCharge">
<span class="text-sm text-secondary">
Since {{ $dayjs(midasSubscription.created).format("MMMM D, YYYY") }}
</span>
<span v-if="midasSubscription.status === 'active'" class="text-sm text-secondary">
Renews {{ $dayjs(midasSubscription.expires).format("MMMM D, YYYY") }}
<span v-if="midasCharge.status === 'open'" class="text-sm text-secondary">
Renews {{ $dayjs(midasCharge.due).format("MMMM D, YYYY") }}
</span>
<span
v-else-if="midasSubscription.status === 'cancelled'"
class="text-sm text-secondary"
>
Expires {{ $dayjs(midasSubscription.expires).format("MMMM D, YYYY") }}
<span v-else-if="midasCharge.status === 'cancelled'" class="text-sm text-secondary">
Expires {{ $dayjs(midasCharge.due).format("MMMM D, YYYY") }}
</span>
</template>
@@ -90,11 +85,11 @@
</span>
</div>
<div
v-if="midasSubscription && midasSubscription.status === 'payment-failed'"
v-if="midasCharge && midasCharge.status === 'failed'"
class="ml-auto flex flex-row-reverse items-center gap-2"
>
<button
v-if="midasSubscription && midasSubscription.status === 'payment-failed'"
v-if="midasCharge && midasCharge.status === 'failed'"
class="iconified-button raised-button"
@click="
() => {
@@ -123,7 +118,7 @@
</OverflowMenu>
</div>
<button
v-else-if="midasSubscription && midasSubscription.status !== 'cancelled'"
v-else-if="midasCharge && midasCharge.status !== 'cancelled'"
class="iconified-button raised-button !ml-auto"
@click="
() => {
@@ -134,6 +129,13 @@
>
<XIcon /> Cancel
</button>
<button
v-else-if="midasCharge && midasCharge.status === 'cancelled'"
class="btn btn-purple btn-large ml-auto"
@click="cancelSubscription(midasSubscription.id, false)"
>
<RightArrowIcon /> Resubscribe
</button>
<button
v-else
class="btn btn-purple btn-large ml-auto"
@@ -474,12 +476,14 @@ function loadStripe() {
const [
{ data: paymentMethods, refresh: refreshPaymentMethods },
{ data: charges, refresh: refreshCharges },
{ data: customer, refresh: refreshCustomer },
{ data: subscriptions, refresh: refreshSubscriptions },
] = await Promise.all([
useAsyncData("billing/payment_methods", () =>
useBaseFetch("billing/payment_methods", { internal: true }),
),
useAsyncData("billing/payments", () => useBaseFetch("billing/payments", { internal: true })),
useAsyncData("billing/customer", () => useBaseFetch("billing/customer", { internal: true })),
useAsyncData("billing/subscriptions", () =>
useBaseFetch("billing/subscriptions", { internal: true }),
@@ -487,18 +491,30 @@ const [
]);
async function refresh() {
await Promise.all([refreshPaymentMethods(), refreshCustomer(), refreshSubscriptions()]);
await Promise.all([
refreshPaymentMethods(),
refreshCharges(),
refreshCustomer(),
refreshSubscriptions(),
]);
}
const midasProduct = ref(products.find((x) => x.metadata.type === "midas"));
const midasSubscription = computed(() =>
subscriptions.value.find((x) => midasProduct.value.prices.find((y) => y.id === x.price_id)),
subscriptions.value.find(
(x) => x.status === "provisioned" && midasProduct.value.prices.find((y) => y.id === x.price_id),
),
);
const midasSubscriptionPrice = computed(() =>
midasSubscription.value
? midasProduct.value.prices.find((x) => x.id === midasSubscription.value.price_id)
: null,
);
const midasCharge = computed(() =>
midasSubscription.value
? charges.value.find((x) => x.subscription_id === midasSubscription.value.id)
: null,
);
const purchaseModal = ref();
const country = useUserCountry();
@@ -524,10 +540,18 @@ if (route.query.priceId && route.query.plan && route.query.redirect_status) {
price_id: route.query.priceId,
interval: route.query.plan,
created: Date.now(),
expires: route.query.plan === "yearly" ? Date.now() + 31536000000 : Date.now() + 2629746000,
status,
});
charges.value.push({
id: "temp",
price_id: route.query.priceId,
subscription_id: "temp",
status: "open",
due: Date.now() + (route.query.plan === "yearly" ? 31536000000 : 2629746000),
subscription_interval: route.query.plan,
});
await router.replace({ query: {} });
}
@@ -655,12 +679,15 @@ async function removePaymentMethod(index) {
}
const cancelSubscriptionId = ref();
async function cancelSubscription(id) {
async function cancelSubscription(id, cancelled) {
startLoading();
try {
await useBaseFetch(`billing/subscription/${id}`, {
internal: true,
method: "DELETE",
method: "PATCH",
body: {
cancelled,
},
});
await refresh();
} catch (err) {

View File

@@ -487,3 +487,154 @@ sharethrough.com, FhiWXM0L, RESELLER, d53b998a7bd4ecd2
amxrtb.com, 105199776, RESELLER
33across.com, 0015a00003ALsDfAAL, DIRECT, bbea06d9c4d2853c
risecodes.com, 661fc591c3a3ef0001984071, DIRECT
optimanetwork.com, 10581, DIRECT
rubiconproject.com, 23404, DIRECT, 0bfd66d529a55807
pubmatic.com,163370,RESELLER,5d62403b186f2ace
criteo.com, B-060927, DIRECT, 9fac4a4a87c2a44f
themediagrid.com, TR634Q, DIRECT, 35d5010d7789b49d
google.com, pub-7094677798399606, RESELLER, f08c47fec0942fa0
openx.com, 544021216, RESELLER, 6a698e2ec38604c6
google.com, pub-2403018226404213, RESELLER, f08c47fec0942fa0
google.com, pub-2730263451308801, RESELLER, f08c47fec0942fa0
google.com, pub-5200956238394958, RESELLER, f08c47fec0942fa0
google.com, pub-5761017298734489, RESELLER, f08c47fec0942fa0
Pubmatic.com, 161094, DIRECT, 5d62403b186f2ace
Pubmatic.com, 162736, DIRECT, 5d62403b186f2ace
rubiconproject.com, 23978, RESELLER, 0bfd66d529a55807
openx.com, 545708355, DIRECT, 6a698e2ec38604c6
openx.com, 558218698, DIRECT, 6a698e2ec38604c6
google.com, pub-3479162065560922, DIRECT, f08c47fec0942fa0
google.com, pub-6631347089063164, DIRECT, f08c47fec0942fa0
google.com, pub-1309378188566785, DIRECT, f08c47fec0942fa0
google.com, pub-1305372857617183, DIRECT, f08c47fec0942fa0
crads.in, CR-0029, DIRECT
google.com, pub-6013343350303951, RESELLER, f08c47fec0942fa0
rtbhouse.com, Jz6bvciZ65MalvqnKChX, DIRECT
incrementx.com, 60039, DIRECT, 8728b7e97e589da4
google.com, pub-3977122154505186, RESELLER, f08c47fec0942fa0
pubmatic.com, 163277, RESELLER, 5d62403b186f2ace
smartadserver.com, 4417-OB, RESELLER, 060d053dcf45cbf3
lijit.com, 381276-eb, RESELLER, fafdf38b16bf6b2b
rubiconproject.com, 22884, RESELLER, 0bfd66d529a55807
onetag.com, 80faba581f6cfb8, RESELLER
onetag.com, 80faba581f6cfb8-OB, RESELLER
axonix.com, 59089, RESELLER, bc385f2b4a87b721
outbrain.com,002d7f7ba0bd74452f2b155d0dfb5cd6c8,RESELLER
opera.com,pub10952251675200,RESELLER,55a0c5fd61378de3
pubmatic.com, 161652, RESELLER, 5d62403b186f2ace
pubmatic.com, 164418, RESELLER, 5d62403b186f2ace
152media.info,152M748,RESELLER
appnexus.com, 3153, RESELLER, f5ab79cb980f11d1
vidoomy.com, 61162, DIRECT
video.unrulymedia.com, 1816262719, RESELLER,
pubmatic.com, 156498, RESELLER, 5d62403b186f2ace
freewheel.tv, 872257, RESELLER
freewheel.tv, 894193, RESELLER
openx.com, 540804929, RESELLER, 6a698e2ec38604c6
google.com, pub-2831120411392012, RESELLER, f08c47fec0942fa0
tremorhub.com, 4cywq-a04wk, RESELLER, 1a4e959a1b50034a
rubiconproject.com, 24386, RESELLER, 0bfd66d529a55807
pubmatic.com, 165144, RESELLER, 5d62403b186f2ace
smartadserver.com, 4984, RESELLER, 060d053dcf45cbf3
truvid.com, 2158, DIRECT
smartadserver.com, 3356, RESELLER, 060d053dcf45cbf3
google.com, pub-6322541192886560, RESELLER, f08c47fec0942fa0
google.com, pub-8787923930478618, RESELLER, f08c47fec0942fa0
google.com, pub-9507736279911916, RESELLER, f08c47fec0942fa0
appnexus.com, 12700, RESELLER, f5ab79cb980f11d1
rubiconproject.com, 17412, RESELLER, 0bfd66d529a55807
conversantmedia.com, 100712, RESELLER, 03113cd04947736d
vidcrunch.com, 63c6b945dee370f45c083ed4, DIRECT
vdo.ai, 2213_3552, DIRECT
atlas5.co, 2213_3552, DIRECT
walletcircle.co, 2213, DIRECT
google.com, pub-9417114411593463, RESELLER, f08c47fec0942fa0
google.com, pub-5717092533913515, RESELLER, f08c47fec0942fa0
aps.amazon.com, 24b39613-fd0f-4009-9189-976a7d9bfd3d, DIRECT
gannett.com, 22655109307, RESELLER
rubiconproject.com, 10968, RESELLER, 0bfd66d529a55807
google.com, pub-4836542095728076, RESELLER, f08c47fec0942fa0
google.com, pub-2930805104418204, RESELLER, f08c47fec0942fa0
google.com, pub-9135355251665930, RESELLER, f08c47fec0942fa0
freewheel.tv, 1139281, RESELLER
aps.amazon.com, 00ed17ab-4189-4639-9d5e-15acd40affde, DIRECT
smartadserver.com, 3686, RESELLER
unibots.in, UBC-0165-1, DIRECT
google.com, pub-1290995901905588, RESELLER, f08c47fec0942fa0
google.com, pub-2603664881560000, RESELLER, f08c47fec0942fa0
google.com, pub-3132893725603935, RESELLER, f08c47fec0942fa0
google.com, pub-3191289882045155, RESELLER, f08c47fec0942fa0
google.com, pub-3328898302928686, RESELLER, f08c47fec0942fa0
google.com, pub-3769010358500643, RESELLER, f08c47fec0942fa0
google.com, pub-5995202563537249, RESELLER, f08c47fec0942fa0
google.com, pub-6151720204273327, RESELLER, f08c47fec0942fa0
google.com, pub-6512936480753445, RESELLER, f08c47fec0942fa0
google.com, pub-8241049497608997, RESELLER, f08c47fec0942fa0
google.com, pub-8610050614645263, RESELLER, f08c47fec0942fa0
google.com, pub-8699255262206653, RESELLER, f08c47fec0942fa0
google.com, pub-9033099948928268, RESELLER, f08c47fec0942fa0
google.com, pub-9467340974789471, RESELLER, f08c47fec0942fa0
google.com, pub-9557089510405422, RESELLER, f08c47fec0942fa0
google.com, pub-9685734445476814, RESELLER, f08c47fec0942fa0
biddo.net, bdc-3969, DIRECT
prodooh.com, pdh-3969, DIRECT
invamia.com, ivm-3969, DIRECT
vidverto.com, vdvt-3969, DIRECT
yieldbird.com, 3969, DIRECT
bidfuse.com, bf-3969, DIRECT
arabella.ag, abl-3969, DIRECT
adtech-digital.com, adt3969, DIRECT
pixfuture.com, 9048, DIRECT
openx.com, 540406323, DIRECT, 6a698e2ec38604c6
pubmatic.com, 158127, RESELLER, 5d62403b186f2ace
sonobi.com, 0b24fdfc82, DIRECT, d1a215d9eb5aee9e
sharethrough.com, 62beb9db, DIRECT, d53b998a7bd4ecd2
d-sail.com, ds0453, DIRECT
google.com, pub-2205121062140812, RESELLER, f08c47fec0942fa0
33across.com, 0010b00002VYZoUAAX, DIRECT, bbea06d9c4d2853c
smartadserver.com, 3663, RESELLER
smartadserver.com, 4071, RESELLER
adtelligent.com, 500592, DIRECT
sovrn.com, 331050, DIRECT, fafdf38b16bf6b2b
rubiconproject.com, 23564, DIRECT, 0bfd66d529a55807
rubiconproject.com, 23566, RESELLER, 0bfd66d529a55807
Media.net, 8CUIUMTP7, DIRECT
e-planning.net, 29459e615aaa9065, DIRECT, c1ba615865ed87b2
themediagrid.com, QDC97I, DIRECT, 35d5010d7789b49d
onetag.com, 79c9089f60042c0, DIRECT
smilewanted.com, 3520, RESELLER
smartadserver.com, 2491, RESELLER
minutemedia.com,01hj1rkkswwe, RESELLER
appnexus.com, 8381, RESELLER, f5ab79cb980f11d1
aniview.com, 60c5dbc56627cd1ce66ff020, RESELLER, 78b21b97965ec3f8
google.com, pub-6346866704322274, RESELLER, f08c47fec0942fa0
google.com, pub-4586415728471297, RESELLER, f08c47fec0942fa0
playstream.media, 911, RESELLER
sharethrough.com, UXUWG46h, RESELLER, d53b998a7bd4ecd2
sharethrough.com, zLsEa05k, RESELLER, d53b998a7bd4ecd2
pubmatic.com, 156557, RESELLER, 5d62403b186f2ace
vidgyor.com,20020, DIRECT
google.com, pub-8863191426564274, RESELLER, f08c47fec0942fa0
pubmatic.com, 162319, RESELLER, 5d62403b186f2ace
lijit.com, 230102, DIRECT, fafdf38b16bf6b2b #SOVRN
lijit.com, 230102-eb, DIRECT, fafdf38b16bf6b2b #SOVRN
video.unrulymedia.com, 2444764291, RESELLER
contextweb.com, 558511, RESELLER, 89ff185a4c4e857c
krushmedia.com, AJxF6R572a9M6CaTvK, RESELLER
inmobi.com, b01aa06531c543d8a5fb9982f60afb00, RESELLER, 83e75a7ae333ca9d
motorik.io, 100463, RESELLER
smaato.com, 1100056344, RESELLER, 07bcf65f187117b4
smartadserver.com, 4926, RESELLER, 060d053dcf45cbf3
onetag.com, 5847a7d7e75dee8, DIRECT
video.unrulymedia.com, 351983115, RESELLER
rubiconproject.com, 15268, RESELLER, 0bfd66d529a55807
pubmatic.com, 159277, RESELLER
appnexus.com, 6849, RESELLER
xad.com, 963, RESELLER, 81cbf0a75a5e0e9a
openx.com, 543878511, RESELLER, 6a698e2ec38604c6
smaato.com, 1100047589, RESELLER, 07bcf65f187117b4
inmobi.com, ba5fd3fb82c5412989b23c3eec71baf7, RESELLER, 83e75a7ae333ca9d
#Criteo
themediagrid.com, 4R7XKQ, DIRECT, 35d5010d7789b49d

View File

@@ -4,6 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Modrinth App Ad</title>
<script src="https://cadmus.script.ac/d14pdm1b7fi5kh/script.js"></script>
<script
src="https://dn0qt3r0xannq.cloudfront.net/modrinth-7JfmkEIXEp/modrinth-longform/prebid-load.js"
async
@@ -45,9 +46,18 @@
<body>
<div class="ads-container">
<div id="plus-link"></div>
<div id="modrinth-rail-1" />
<div id="modrinth-rail-1"></div>
</div>
<script>
function getCookie(name) {
function escape(s) {
return s.replace(/([.*+?\^$(){}|\[\]\/\\])/g, "\\$1");
}
const match = document.cookie.match(RegExp("(?:^|;\\s*)" + escape(name) + "=([^;]*)"));
return match ? match[1] : null;
}
function initAds(personalized) {
window.tude = window.tude || { cmd: [] };
@@ -56,6 +66,9 @@
{
divId: "modrinth-rail-1",
baseDivId: "pb-slot-square-2",
targeting: {
location: "app",
},
},
]);
@@ -65,10 +78,19 @@
});
}
window.__TAURI_INTERNALS__
.invoke("plugin:ads|get_ads_personalization", {})
.then(initAds)
.catch(() => initAds(true));
try {
if (window.__TAURI_INTERNALS__) {
window.__TAURI_INTERNALS__
.invoke("plugin:ads|get_ads_personalization", {})
.then(initAds)
.catch(() => initAds(true));
} else {
initAds(true);
}
} catch (err) {
initAds(true);
console.error(err);
}
window.addEventListener(
"message",

View File

@@ -1,6 +1,6 @@
[package]
name = "theseus"
version = "0.8.8"
version = "0.8.9"
authors = ["Jai A <jaiagr+gpg@pm.me>"]
edition = "2021"

View File

@@ -540,8 +540,11 @@ async function refreshPayment(confirmationId, paymentMethodId) {
}
const result = await props.sendBillingRequest({
product_id: props.product.id,
interval: selectedPlan.value,
charge: {
type: 'new',
product_id: props.product.id,
interval: selectedPlan.value,
},
existing_payment_intent: paymentIntentId.value,
...base,
})