mirror of
https://github.com/appwrite/console.git
synced 2026-06-06 19:27:48 +00:00
Merge pull request #1624 from appwrite/mobile-onboarding-flows
Feat: New mobile onboarding flows
This commit is contained in:
@@ -38,9 +38,11 @@
|
||||
{disabled}
|
||||
title={title ?? slotTitle?.innerText}
|
||||
bind:group>
|
||||
<p>
|
||||
<slot />
|
||||
</p>
|
||||
{#if $$slots.default}
|
||||
<p>
|
||||
<slot />
|
||||
</p>
|
||||
{/if}
|
||||
</Card.Selector>
|
||||
</div>
|
||||
<span slot="tooltip">{tooltipText}</span>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { trackEvent } from '$lib/actions/analytics';
|
||||
import WizardExitModal from './wizardExitModal.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
|
||||
type $$Props =
|
||||
| {
|
||||
@@ -13,6 +14,7 @@
|
||||
invertColumns?: boolean;
|
||||
hideAside?: boolean;
|
||||
hideFooter?: boolean;
|
||||
onExit?: () => void;
|
||||
}
|
||||
| {
|
||||
title: string;
|
||||
@@ -22,6 +24,7 @@
|
||||
invertColumns?: boolean;
|
||||
hideAside?: boolean;
|
||||
hideFooter?: boolean;
|
||||
onExit?: () => void;
|
||||
};
|
||||
|
||||
export let title: $$Props['title'] = '';
|
||||
@@ -31,6 +34,7 @@
|
||||
export let invertColumns: $$Props['invertColumns'] = false;
|
||||
export let hideAside = false;
|
||||
export let hideFooter = false;
|
||||
export let onExit: $$Props['onExit'] = undefined;
|
||||
|
||||
function handleKeydown(event: KeyboardEvent) {
|
||||
if (event.key === 'Escape') {
|
||||
@@ -83,6 +87,14 @@
|
||||
trackEvent('wizard_exit', {
|
||||
from: 'prompt'
|
||||
});
|
||||
|
||||
wizard.hide();
|
||||
if (onExit) {
|
||||
onExit();
|
||||
|
||||
// clear exit
|
||||
onExit = null;
|
||||
}
|
||||
}}>
|
||||
<slot name="exit">
|
||||
Are you sure you want to exit from this process? All data will be deleted. This action
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { Button, Step, Link, Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { Step, Link, Icon, Layout } from '@appwrite.io/pink-svelte';
|
||||
import { addPlatform } from './platforms/+page.svelte';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { user } from '$lib/stores/user';
|
||||
import { IconArrowRight } from '@appwrite.io/pink-icons-svelte';
|
||||
import DatabaseImgSource from './assets/database.png';
|
||||
import DatabaseImgSourceDark from './assets/database-dark.png';
|
||||
@@ -21,10 +20,8 @@
|
||||
import PlatformFlutterImgSource from './assets/platform-flutter.png';
|
||||
import PlatformFlutterImgSourceDark from './assets/platform-flutter-dark.png';
|
||||
import { base } from '$app/paths';
|
||||
import { hasOnboardingDismissed, setHasOnboardingDismissed } from '$lib/helpers/onboarding';
|
||||
import Wizard from './keys/wizard.svelte';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { goto } from '$app/navigation';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
function createKey() {
|
||||
@@ -72,7 +69,7 @@
|
||||
on:click={() => addPlatform(0)}>
|
||||
<Layout.Stack direction="column" justifyContent="space-between">
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? PlatformWebImgSourceDark
|
||||
: PlatformWebImgSource}
|
||||
alt="" />
|
||||
@@ -94,7 +91,7 @@
|
||||
on:click={createKey}>
|
||||
<Layout.Stack direction="column" justifyContent="space-between">
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? PlatformServerImgSourceDark
|
||||
: PlatformServerImgSource}
|
||||
alt="" />
|
||||
@@ -115,7 +112,7 @@
|
||||
on:click={() => addPlatform(3)}>
|
||||
<Layout.Stack direction="column" justifyContent="space-between">
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? PlatformIosImgSourceDark
|
||||
: PlatformIosImgSource}
|
||||
alt="" />
|
||||
@@ -209,7 +206,7 @@
|
||||
href={`${base}/project-${projectId}/databases`}>
|
||||
<Layout.Stack direction="column" justifyContent="space-between">
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? DatabaseImgSourceDark
|
||||
: DatabaseImgSource}
|
||||
alt="" />
|
||||
@@ -280,7 +277,7 @@
|
||||
</Layout.Stack>
|
||||
</div>
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? UsersImgSourceDark
|
||||
: UsersImgSource}
|
||||
alt="" />
|
||||
@@ -289,7 +286,7 @@
|
||||
<div class="card-content">
|
||||
<Layout.Stack direction="column" justifyContent="space-between">
|
||||
<img
|
||||
src={$app.themeInUse == 'dark'
|
||||
src={$app.themeInUse === 'dark'
|
||||
? DiscordImgSourceDark
|
||||
: DiscordImgSource}
|
||||
class="discord"
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
import CreateAndroid from './createAndroid.svelte';
|
||||
import CreateApple from './createApple.svelte';
|
||||
import CreateFlutter from './createFlutter.svelte';
|
||||
import CreateWeb from './createWeb.svelte';
|
||||
import CreateReactNative from './createReactNative.svelte';
|
||||
import { versions } from './wizard/store';
|
||||
|
||||
@@ -23,7 +22,6 @@
|
||||
}
|
||||
|
||||
const platforms = {
|
||||
[Platform.Web]: CreateWeb,
|
||||
[Platform.Flutter]: CreateFlutter,
|
||||
[Platform.Android]: CreateAndroid,
|
||||
[Platform.Apple]: CreateApple,
|
||||
@@ -56,7 +54,6 @@
|
||||
'flutter-macos' = 'macOS',
|
||||
'flutter-windows' = 'Windows',
|
||||
'flutter-web' = 'Web',
|
||||
'web' = 'Web',
|
||||
'react-native-android' = 'Android',
|
||||
'react-native-ios' = 'iOS'
|
||||
}
|
||||
@@ -73,8 +70,6 @@
|
||||
return 'color/apple';
|
||||
} else if (platform.includes('android')) {
|
||||
return 'color/android';
|
||||
} else if (platform.includes('web')) {
|
||||
return 'grayscale/code';
|
||||
} else {
|
||||
return 'unknown';
|
||||
}
|
||||
@@ -95,7 +90,6 @@
|
||||
</Button>
|
||||
{/if}
|
||||
<svelte:fragment slot="list">
|
||||
<DropListItem on:click={() => addPlatform(Platform.Web)}>Web app</DropListItem>
|
||||
<DropListItem on:click={() => addPlatform(Platform.Flutter)}>Flutter app</DropListItem>
|
||||
<DropListItem on:click={() => addPlatform(Platform.Android)}>Android app</DropListItem>
|
||||
<DropListItem on:click={() => addPlatform(Platform.Apple)}>Apple app</DropListItem>
|
||||
@@ -169,9 +163,6 @@
|
||||
</Button>
|
||||
{/if}
|
||||
<svelte:fragment slot="list">
|
||||
<DropListItem on:click={() => addPlatform(Platform.Web)}>
|
||||
Web
|
||||
</DropListItem>
|
||||
<DropListItem on:click={() => addPlatform(Platform.Flutter)}>
|
||||
Flutter
|
||||
</DropListItem>
|
||||
@@ -181,6 +172,9 @@
|
||||
<DropListItem on:click={() => addPlatform(Platform.Apple)}>
|
||||
Apple
|
||||
</DropListItem>
|
||||
<DropListItem on:click={() => addPlatform(Platform.ReactNative)}>
|
||||
React Native
|
||||
</DropListItem>
|
||||
</svelte:fragment>
|
||||
</DropList>
|
||||
</div>
|
||||
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
<script lang="ts">
|
||||
import { Icon } from '@appwrite.io/pink-svelte';
|
||||
import { IconCheck } from '@appwrite.io/pink-icons-svelte';
|
||||
|
||||
export let status: boolean = false;
|
||||
</script>
|
||||
|
||||
<div class="connection-line u-flex u-cross-center">
|
||||
<div
|
||||
class="line-left"
|
||||
style={`opacity: ${status ? 1 : 0.15}; transition: opacity 5s;`}
|
||||
data-status={status}>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="tick-container"
|
||||
style={`opacity: ${status ? 1 : 0.15}; transition: opacity 2.5s;`}
|
||||
data-status={status}>
|
||||
{#if status}
|
||||
<!-- todo: xs missing atm, need to test -->
|
||||
<Icon icon={IconCheck} size="s" color="#fd366e" />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="line-right"
|
||||
style={`opacity: ${status ? 1 : 0.15}; transition: opacity 5s;`}
|
||||
data-status={status}>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.connection-line {
|
||||
display: flex;
|
||||
width: 6.125rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.line-left[data-status='false'],
|
||||
.line-right[data-status='false'] {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: none;
|
||||
border-top: 1px dashed #d8d8db;
|
||||
}
|
||||
|
||||
.line-left[data-status='true'] {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(to left, #f02e65 0%, rgba(254, 149, 103, 0.15) 100%);
|
||||
}
|
||||
|
||||
.line-right[data-status='true'] {
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(to right, #f02e65 6.32%, rgba(254, 149, 103, 0.15) 116.81%);
|
||||
}
|
||||
|
||||
.tick-container[data-status='false'] {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
display: flex;
|
||||
border-radius: 50%;
|
||||
margin-inline: 0.25rem;
|
||||
background-color: #ccc;
|
||||
}
|
||||
|
||||
.tick-container[data-status='true'] {
|
||||
display: flex;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
color: #fd366e;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1.8px solid hsla(343, 98%, 60%, 0.32);
|
||||
background-color: hsla(343, 98%, 60%, 0.08);
|
||||
}
|
||||
</style>
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<script lang="ts">
|
||||
import type { ComponentType } from 'svelte';
|
||||
|
||||
export let icon: ComponentType;
|
||||
export let iconSize: number | undefined = undefined;
|
||||
export let iconColor: string | undefined = undefined;
|
||||
</script>
|
||||
|
||||
<div class="outer-card">
|
||||
<div
|
||||
class="inner-card"
|
||||
style="
|
||||
--icon-color: {iconColor || 'inherit'};
|
||||
--icon-size: {iconSize ? `${iconSize}rem` : 'inherit'};
|
||||
">
|
||||
<svelte:component this={icon} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
.outer-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 94.304px;
|
||||
height: 94.303px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 26.944px;
|
||||
border: 1.684px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
box-shadow: 0 8.757px 8.757px 0 rgba(0, 0, 0, 0.04);
|
||||
}
|
||||
|
||||
.inner-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 80.832px;
|
||||
height: 80.831px;
|
||||
flex-shrink: 0;
|
||||
border-radius: 20.208px;
|
||||
background: #fff;
|
||||
border: 0.54px solid #ededf0;
|
||||
box-shadow: 0 6.736px 6.736px 0 rgba(0, 0, 0, 0.05);
|
||||
|
||||
& :global(svg) {
|
||||
width: var(--icon-size);
|
||||
height: var(--icon-size);
|
||||
color: var(--icon-color);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.theme-dark) {
|
||||
& .outer-card {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
|
||||
& .inner-card {
|
||||
border: 0.54px solid rgba(237, 237, 240, 0.08);
|
||||
background: var(--color-bgColor-neutral-primary, #1d1d21);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,46 +1,247 @@
|
||||
<script lang="ts">
|
||||
import { WizardWithSteps } from '$lib/layout';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import type { WizardStepsType } from '$lib/layout/wizardWithSteps.svelte';
|
||||
import Step1 from './wizard/android/step1.svelte';
|
||||
import Step2 from './wizard/android/step2.svelte';
|
||||
import Step3 from './wizard/android/step3.svelte';
|
||||
import Step4 from './wizard/step4.svelte';
|
||||
import {
|
||||
Code,
|
||||
Layout,
|
||||
Icon,
|
||||
Typography,
|
||||
Fieldset,
|
||||
InlineCode,
|
||||
Spinner
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Button, Form, InputText } from '$lib/elements/forms';
|
||||
import { IconAndroid, IconAppwrite } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card } from '$lib/components';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ConnectionLine from './components/ConnectionLine.svelte';
|
||||
import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isCloud } from '$lib/system';
|
||||
|
||||
async function onFinish() {
|
||||
await Promise.all([invalidate(Dependencies.PROJECT), invalidate(Dependencies.PLATFORMS)]);
|
||||
createPlatform.reset();
|
||||
wizard.hide();
|
||||
let showExitModal = false;
|
||||
let isPlatformCreated = false;
|
||||
let isCreatingPlatform = false;
|
||||
let connectionSuccessful = false;
|
||||
const projectId = $page.params.project;
|
||||
|
||||
const gitCloneCode =
|
||||
'\ngit clone https://github.com/appwrite/starter-for-android\ncd starter-for-android\n';
|
||||
|
||||
const updateConfigCode = isCloud
|
||||
? `const val APPWRITE_PROJECT_ID = "${projectId}"`
|
||||
: `const val APPWRITE_PROJECT_ID = "${projectId}"
|
||||
const val APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject.client.config.endpoint}"
|
||||
`;
|
||||
|
||||
async function createAndroidPlatform() {
|
||||
try {
|
||||
isCreatingPlatform = true;
|
||||
await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
PlatformType.Android,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
isPlatformCreated = true;
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: 'android'
|
||||
});
|
||||
await Promise.all([
|
||||
invalidate(Dependencies.PROJECT),
|
||||
invalidate(Dependencies.PLATFORMS)
|
||||
]);
|
||||
} catch (error) {
|
||||
trackError(error, Submit.PlatformCreate);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} finally {
|
||||
isCreatingPlatform = false;
|
||||
}
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Settings',
|
||||
component: Step1
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Install',
|
||||
component: Step2,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
label: 'Import',
|
||||
component: Step3,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
label: 'Build',
|
||||
component: Step4,
|
||||
optional: true
|
||||
async function resetPlatformStore() {
|
||||
createPlatform.reset();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => {
|
||||
if (response.events.includes(`projects.${projectId}.ping`) && isPlatformCreated) {
|
||||
connectionSuccessful = true;
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
resetPlatformStore();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<WizardWithSteps
|
||||
title="Add an Android platform"
|
||||
steps={stepsComponents}
|
||||
on:finish={onFinish}
|
||||
on:exit={onFinish}
|
||||
finalAction="Go to dashboard" />
|
||||
<Wizard title="Add Android platform" bind:showExitModal confirmExit>
|
||||
<Form onSubmit={createAndroidPlatform}>
|
||||
<Layout.Stack gap="xxl">
|
||||
<!-- Step One -->
|
||||
{#if !isPlatformCreated}
|
||||
<Fieldset legend="Details">
|
||||
<Layout.Stack gap="l" alignItems="flex-end">
|
||||
<Layout.Stack gap="s">
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="My Android App"
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
|
||||
<!-- Tooltips on InputText don't work as of now -->
|
||||
<InputText
|
||||
id="key"
|
||||
label="Package name"
|
||||
placeholder="com.company.appname"
|
||||
tooltip="Your package name is generally the applicationId in your app-level build.gradle file."
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Button
|
||||
fullWidthMobile
|
||||
size="s"
|
||||
submit
|
||||
forceShowLoader
|
||||
submissionLoader={isCreatingPlatform}
|
||||
disabled={!$createPlatform.name ||
|
||||
!$createPlatform.key ||
|
||||
isCreatingPlatform}>
|
||||
Create platform
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{:else}
|
||||
<Layout.Stack gap="xxl">
|
||||
<Card isTile padding="s" radius="s">
|
||||
<Layout.Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap="xs">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
<Icon size="m" icon={IconAndroid} />
|
||||
<Typography.Text
|
||||
variant="m-400"
|
||||
color="--color-fgcolor-neutral-primary">
|
||||
{$createPlatform.name} ({$createPlatform.key})
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
|
||||
<!-- Step Two -->
|
||||
{#if isPlatformCreated}
|
||||
<Fieldset legend="Clone starter">
|
||||
<Layout.Stack gap="l">
|
||||
<Typography.Text variant="m-500">
|
||||
1. Clone the starter kit from GitHub using the terminal or Android
|
||||
Studio.
|
||||
</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="bash" lineNumbers code={gitCloneCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>2. Open the file <InlineCode
|
||||
size="s"
|
||||
code="data/repository/AppwriteRepository.kt" /> and update the configuration
|
||||
settings.</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="kotlin" lineNumbers code={updateConfigCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>3. Run the app on a connected device or emulator, then click the <InlineCode
|
||||
size="s"
|
||||
code="Send a ping" /> button to verify the setup.</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
<svelte:fragment slot="aside">
|
||||
<Card padding="l" class="responsive-padding">
|
||||
<Layout.Stack gap="xxl">
|
||||
<Layout.Stack direction="row" justifyContent="center" gap="none">
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#3ddc84"
|
||||
icon={IconAndroid} />
|
||||
|
||||
<ConnectionLine status={connectionSuccessful} />
|
||||
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#FD366E"
|
||||
icon={IconAppwrite} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Layout.Stack direction="row" justifyContent="center" alignItems="center" gap="l">
|
||||
{#if !connectionSuccessful}
|
||||
<Spinner />
|
||||
<Typography.Text variant="m-400">Waiting for connection...</Typography.Text>
|
||||
{:else}
|
||||
<!-- cannot apply fade on components -->
|
||||
<div
|
||||
in:fade={{ duration: 2500 }}
|
||||
class="u-flex u-flex-vertical u-cross-center u-gap-8">
|
||||
<Typography.Title size="m">Congratulations!</Typography.Title>
|
||||
|
||||
<Typography.Text variant="m-400"
|
||||
>You connected your app successfully.</Typography.Text>
|
||||
</div>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button
|
||||
size="s"
|
||||
fullWidthMobile
|
||||
secondary
|
||||
disabled={isCreatingPlatform}
|
||||
href={`${base}/project-${projectId}/overview`}>
|
||||
Go to dashboard
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</Wizard>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.pink2-code-margin-fix pre) {
|
||||
margin: revert;
|
||||
}
|
||||
|
||||
:global(.responsive-padding) {
|
||||
@media (max-width: 768px) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,47 +1,271 @@
|
||||
<script lang="ts">
|
||||
import { WizardWithSteps } from '$lib/layout';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizardWithSteps.svelte';
|
||||
import Step1 from './wizard/apple/step1.svelte';
|
||||
import Step2 from './wizard/apple/step2.svelte';
|
||||
import Step3 from './wizard/apple/step3.svelte';
|
||||
import Step4 from './wizard/step4.svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import {
|
||||
Code,
|
||||
Layout,
|
||||
Icon,
|
||||
Typography,
|
||||
Fieldset,
|
||||
InlineCode,
|
||||
Spinner
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Button, Form, InputText } from '$lib/elements/forms';
|
||||
import { IconApple, IconAppwrite } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card } from '$lib/components';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ConnectionLine from './components/ConnectionLine.svelte';
|
||||
import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { app } from '$lib/stores/app';
|
||||
import { LabelCard } from '$lib/components';
|
||||
|
||||
async function onFinish() {
|
||||
await Promise.all([invalidate(Dependencies.PROJECT), invalidate(Dependencies.PLATFORMS)]);
|
||||
let showExitModal = false;
|
||||
let isPlatformCreated = false;
|
||||
let isCreatingPlatform = false;
|
||||
let connectionSuccessful = false;
|
||||
const projectId = $page.params.project;
|
||||
|
||||
createPlatform.reset();
|
||||
wizard.hide();
|
||||
const gitCloneCode =
|
||||
'\ngit clone https://github.com/appwrite/starter-for-ios\ncd starter-for-ios\n';
|
||||
|
||||
const updateConfigCode = isCloud
|
||||
? `APPWRITE_PROJECT_ID: "${projectId}"`
|
||||
: `APPWRITE_PROJECT_ID: "${projectId}"
|
||||
APPWRITE_PUBLIC_ENDPOINT: "${sdk.forProject.client.config.endpoint}"
|
||||
`;
|
||||
|
||||
let platform: PlatformType = PlatformType.Appleios;
|
||||
|
||||
let platforms: { [key: string]: PlatformType } = {
|
||||
iOS: PlatformType.Appleios,
|
||||
macOS: PlatformType.Applemacos,
|
||||
watchOS: PlatformType.Applewatchos,
|
||||
tvOS: PlatformType.Appletvos
|
||||
};
|
||||
|
||||
async function createApplePlatform() {
|
||||
try {
|
||||
isCreatingPlatform = true;
|
||||
await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
isPlatformCreated = true;
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
await Promise.all([
|
||||
invalidate(Dependencies.PROJECT),
|
||||
invalidate(Dependencies.PLATFORMS)
|
||||
]);
|
||||
} catch (error) {
|
||||
trackError(error, Submit.PlatformCreate);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} finally {
|
||||
isCreatingPlatform = false;
|
||||
}
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Settings',
|
||||
component: Step1
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Install',
|
||||
component: Step2,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
label: 'Import',
|
||||
component: Step3,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
label: 'Build',
|
||||
component: Step4,
|
||||
optional: true
|
||||
async function resetPlatformStore() {
|
||||
createPlatform.reset();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => {
|
||||
if (response.events.includes(`projects.${projectId}.ping`) && isPlatformCreated) {
|
||||
connectionSuccessful = true;
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
resetPlatformStore();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<WizardWithSteps
|
||||
title="Add an Apple platform"
|
||||
steps={stepsComponents}
|
||||
on:finish={onFinish}
|
||||
on:exit={onFinish}
|
||||
finalAction="Go to dashboard" />
|
||||
<Wizard title="Add Apple platform" bind:showExitModal confirmExit>
|
||||
<Form onSubmit={createApplePlatform}>
|
||||
<Layout.Stack gap="xxl">
|
||||
<!-- Step One -->
|
||||
<Layout.Stack gap="l" direction="row">
|
||||
{#each Object.entries(platforms) as [key, value]}
|
||||
<div class="u-width-full-line">
|
||||
<!-- TODO: https://github.com/appwrite/pink/pull/248 for correct spacing -->
|
||||
<LabelCard
|
||||
name={key}
|
||||
bind:group={platform}
|
||||
variant="primary"
|
||||
{value}
|
||||
title={key} />
|
||||
</div>
|
||||
{/each}
|
||||
</Layout.Stack>
|
||||
|
||||
<!-- Step Two -->
|
||||
{#if !isPlatformCreated}
|
||||
<Fieldset legend="Details">
|
||||
<Layout.Stack gap="l" alignItems="flex-end">
|
||||
<Layout.Stack gap="s">
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="My Apple App"
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
|
||||
<!-- Tooltips on InputText don't work as of now -->
|
||||
<InputText
|
||||
id="hostname"
|
||||
label="Bundle ID"
|
||||
placeholder="com.company.appname"
|
||||
tooltip="You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Button
|
||||
fullWidthMobile
|
||||
size="s"
|
||||
submit
|
||||
forceShowLoader
|
||||
submissionLoader={isCreatingPlatform}
|
||||
disabled={!platform ||
|
||||
!$createPlatform.name ||
|
||||
!$createPlatform.key ||
|
||||
isCreatingPlatform}>
|
||||
Create platform
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{:else}
|
||||
<Layout.Stack gap="xxl">
|
||||
<Card isTile padding="s" radius="s">
|
||||
<Layout.Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap="xs">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
<Icon size="m" icon={IconApple} />
|
||||
<Typography.Text
|
||||
variant="m-400"
|
||||
color="--color-fgcolor-neutral-primary">
|
||||
{$createPlatform.name} ({$createPlatform.key})
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
|
||||
<!-- Step Three -->
|
||||
{#if isPlatformCreated}
|
||||
<Fieldset legend="Clone starter">
|
||||
<Layout.Stack gap="l">
|
||||
<Typography.Text variant="m-500">
|
||||
1. Clone the starter kit from GitHub using the terminal or XCode.
|
||||
</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="bash" lineNumbers code={gitCloneCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>2. Open the file <InlineCode size="s" code="Sources/Config.plist" /> and
|
||||
update the configuration settings.</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="plaintext" lineNumbers code={updateConfigCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>3. Run the app on a connected device or simulator, then click the <InlineCode
|
||||
size="s"
|
||||
code="Send a ping" /> button to verify the setup.</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
<svelte:fragment slot="aside">
|
||||
<Card padding="l" class="responsive-padding">
|
||||
<Layout.Stack gap="xxl">
|
||||
<Layout.Stack direction="row" justifyContent="center" gap="none">
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor={$app.themeInUse === 'light' ? '#000' : '#fff'}
|
||||
icon={IconApple} />
|
||||
|
||||
<ConnectionLine status={connectionSuccessful} />
|
||||
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#FD366E"
|
||||
icon={IconAppwrite} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Layout.Stack direction="row" justifyContent="center" alignItems="center" gap="l">
|
||||
{#if !connectionSuccessful}
|
||||
<Spinner />
|
||||
<Typography.Text variant="m-400">Waiting for connection...</Typography.Text>
|
||||
{:else}
|
||||
<!-- cannot apply fade on components -->
|
||||
<div
|
||||
in:fade={{ duration: 2500 }}
|
||||
class="u-flex u-flex-vertical u-cross-center u-gap-8">
|
||||
<Typography.Title size="m">Congratulations!</Typography.Title>
|
||||
|
||||
<Typography.Text variant="m-400"
|
||||
>You connected your app successfully.</Typography.Text>
|
||||
</div>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button
|
||||
size="s"
|
||||
fullWidthMobile
|
||||
secondary
|
||||
disabled={isCreatingPlatform}
|
||||
href={`${base}/project-${projectId}/overview`}>
|
||||
Go to dashboard
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</Wizard>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.pink2-code-margin-fix pre) {
|
||||
margin: revert;
|
||||
}
|
||||
|
||||
:global(.responsive-padding) {
|
||||
@media (max-width: 768px) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,47 +1,329 @@
|
||||
<script lang="ts">
|
||||
import { WizardWithSteps } from '$lib/layout';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizardWithSteps.svelte';
|
||||
import Step1 from './wizard/flutter/step1.svelte';
|
||||
import Step2 from './wizard/flutter/step2.svelte';
|
||||
import Step3 from './wizard/flutter/step3.svelte';
|
||||
import Step4 from './wizard/step4.svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import {
|
||||
Code,
|
||||
Layout,
|
||||
Icon,
|
||||
Typography,
|
||||
Fieldset,
|
||||
InlineCode,
|
||||
Spinner
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Button, Form, InputText } from '$lib/elements/forms';
|
||||
import { IconFlutter, IconAppwrite } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card } from '$lib/components';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ConnectionLine from './components/ConnectionLine.svelte';
|
||||
import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { LabelCard } from '$lib/components';
|
||||
|
||||
async function onFinish() {
|
||||
await Promise.all([invalidate(Dependencies.PROJECT), invalidate(Dependencies.PLATFORMS)]);
|
||||
let showExitModal = false;
|
||||
let isPlatformCreated = false;
|
||||
let isCreatingPlatform = false;
|
||||
let connectionSuccessful = false;
|
||||
const projectId = $page.params.project;
|
||||
|
||||
createPlatform.reset();
|
||||
wizard.hide();
|
||||
const gitCloneCode =
|
||||
'\ngit clone https://github.com/appwrite/starter-for-flutter\ncd starter-for-flutter\n';
|
||||
|
||||
const updateConfigCode = isCloud
|
||||
? `static const String APPWRITE_PROJECT_ID = "${projectId}"`
|
||||
: `static const String APPWRITE_PROJECT_ID = "${projectId}"
|
||||
static const String APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject.client.config.endpoint}"
|
||||
`;
|
||||
|
||||
let platform: PlatformType = PlatformType.Flutterandroid;
|
||||
|
||||
let platforms: { [key: string]: PlatformType } = {
|
||||
Android: PlatformType.Flutterandroid,
|
||||
iOS: PlatformType.Flutterios,
|
||||
Linux: PlatformType.Flutterlinux,
|
||||
macOS: PlatformType.Fluttermacos,
|
||||
Windows: PlatformType.Flutterwindows,
|
||||
Web: PlatformType.Flutterweb
|
||||
};
|
||||
|
||||
const placeholder: Partial<
|
||||
Record<
|
||||
PlatformType,
|
||||
{
|
||||
name: string;
|
||||
hostname: string;
|
||||
tooltip: string;
|
||||
}
|
||||
>
|
||||
> = {
|
||||
[PlatformType.Flutterandroid]: {
|
||||
name: 'My Android App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
'Your package name is generally the applicationId in your app-level build.gradle file.'
|
||||
},
|
||||
[PlatformType.Flutterios]: {
|
||||
name: 'My iOS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
},
|
||||
[PlatformType.Flutterlinux]: {
|
||||
name: 'My Linux App',
|
||||
hostname: 'appname',
|
||||
tooltip: 'Your application name'
|
||||
},
|
||||
[PlatformType.Fluttermacos]: {
|
||||
name: 'My mac OS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
},
|
||||
[PlatformType.Flutterwindows]: {
|
||||
name: 'My Windows App',
|
||||
hostname: 'appname',
|
||||
tooltip: 'Your application name'
|
||||
},
|
||||
[PlatformType.Flutterweb]: {
|
||||
name: 'My Web App',
|
||||
hostname: 'localhost',
|
||||
tooltip:
|
||||
'The hostname that your website will use to interact with the Appwrite APIs in production or development environments. No protocol or port number required.'
|
||||
}
|
||||
};
|
||||
|
||||
const hostname: Partial<Record<PlatformType, string>> = {
|
||||
[PlatformType.Flutterandroid]: 'Package Name',
|
||||
[PlatformType.Flutterios]: 'Bundle ID',
|
||||
[PlatformType.Flutterlinux]: 'Package Name',
|
||||
[PlatformType.Fluttermacos]: 'Bundle ID',
|
||||
[PlatformType.Flutterweb]: 'Hostname',
|
||||
[PlatformType.Flutterwindows]: 'Package Name'
|
||||
};
|
||||
|
||||
async function createFlutterPlatform() {
|
||||
try {
|
||||
isCreatingPlatform = true;
|
||||
await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
isPlatformCreated = true;
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
await Promise.all([
|
||||
invalidate(Dependencies.PROJECT),
|
||||
invalidate(Dependencies.PLATFORMS)
|
||||
]);
|
||||
} catch (error) {
|
||||
trackError(error, Submit.PlatformCreate);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} finally {
|
||||
isCreatingPlatform = false;
|
||||
}
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Settings',
|
||||
component: Step1
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Install',
|
||||
component: Step2,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
label: 'Import',
|
||||
component: Step3,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
label: 'Build',
|
||||
component: Step4,
|
||||
optional: true
|
||||
async function resetPlatformStore() {
|
||||
createPlatform.reset();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => {
|
||||
if (response.events.includes(`projects.${projectId}.ping`) && isPlatformCreated) {
|
||||
connectionSuccessful = true;
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
resetPlatformStore();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<WizardWithSteps
|
||||
title="Add a Flutter platform"
|
||||
steps={stepsComponents}
|
||||
on:finish={onFinish}
|
||||
on:exit={onFinish}
|
||||
finalAction="Go to dashboard" />
|
||||
<Wizard title="Add Flutter platform" bind:showExitModal confirmExit>
|
||||
<Form onSubmit={createFlutterPlatform}>
|
||||
<Layout.Stack gap="xxl">
|
||||
<!-- Step One -->
|
||||
<Layout.Stack gap="l" direction="row">
|
||||
{#each Object.entries(platforms) as [key, value]}
|
||||
<div class="u-width-full-line">
|
||||
<!-- TODO: https://github.com/appwrite/pink/pull/248 for correct spacing -->
|
||||
<LabelCard
|
||||
name={key}
|
||||
bind:group={platform}
|
||||
variant="primary"
|
||||
{value}
|
||||
title={key} />
|
||||
</div>
|
||||
{/each}
|
||||
</Layout.Stack>
|
||||
|
||||
<!-- Step Two -->
|
||||
{#if !isPlatformCreated}
|
||||
<Fieldset legend="Details">
|
||||
<Layout.Stack gap="l" alignItems="flex-end">
|
||||
<Layout.Stack gap="s">
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder={placeholder[platform].name}
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
|
||||
<!-- Tooltips on InputText don't work as of now -->
|
||||
<InputText
|
||||
id="hostname"
|
||||
label={hostname[platform]}
|
||||
placeholder={placeholder[platform].hostname}
|
||||
tooltip={placeholder[platform].tooltip}
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Button
|
||||
fullWidthMobile
|
||||
size="s"
|
||||
submit
|
||||
forceShowLoader
|
||||
submissionLoader={isCreatingPlatform}
|
||||
disabled={!platform ||
|
||||
!$createPlatform.name ||
|
||||
!$createPlatform.key ||
|
||||
isCreatingPlatform}>
|
||||
Create platform
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{:else}
|
||||
<Layout.Stack gap="xxl">
|
||||
<Card isTile padding="s" radius="s">
|
||||
<Layout.Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap="xs">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
<Icon size="m" icon={IconFlutter} />
|
||||
<Typography.Text
|
||||
variant="m-400"
|
||||
color="--color-fgcolor-neutral-primary">
|
||||
{$createPlatform.name} ({$createPlatform.key})
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
|
||||
<!-- Step Three -->
|
||||
{#if isPlatformCreated}
|
||||
<Fieldset legend="Clone starter">
|
||||
<Layout.Stack gap="l">
|
||||
<Typography.Text variant="m-500">
|
||||
1. Clone the starter kit from GitHub using the terminal, Android Studio
|
||||
or VSCode.
|
||||
</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="bash" lineNumbers code={gitCloneCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>2. Open the file <InlineCode
|
||||
size="s"
|
||||
code="lib/constants/appwrite.dart" /> and update the configuration settings.</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="dart" lineNumbers code={updateConfigCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>3. Run the app on a connected device or simulator, then click the <InlineCode
|
||||
size="s"
|
||||
code="Send a ping" /> button to verify the setup.</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
<svelte:fragment slot="aside">
|
||||
<Card padding="l" class="responsive-padding">
|
||||
<Layout.Stack gap="xxl">
|
||||
<Layout.Stack direction="row" justifyContent="center" gap="none">
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#47C5FB"
|
||||
icon={IconFlutter} />
|
||||
|
||||
<ConnectionLine status={connectionSuccessful} />
|
||||
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#FD366E"
|
||||
icon={IconAppwrite} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Layout.Stack direction="row" justifyContent="center" alignItems="center" gap="l">
|
||||
{#if !connectionSuccessful}
|
||||
<Spinner />
|
||||
<Typography.Text variant="m-400">Waiting for connection...</Typography.Text>
|
||||
{:else}
|
||||
<!-- cannot apply fade on components -->
|
||||
<div
|
||||
in:fade={{ duration: 2500 }}
|
||||
class="u-flex u-flex-vertical u-cross-center u-gap-8">
|
||||
<Typography.Title size="m">Congratulations!</Typography.Title>
|
||||
|
||||
<Typography.Text variant="m-400"
|
||||
>You connected your app successfully.</Typography.Text>
|
||||
</div>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button
|
||||
size="s"
|
||||
fullWidthMobile
|
||||
secondary
|
||||
disabled={isCreatingPlatform}
|
||||
href={`${base}/project-${projectId}/overview`}>
|
||||
Go to dashboard
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</Wizard>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.pink2-code-margin-fix pre) {
|
||||
margin: revert;
|
||||
}
|
||||
|
||||
:global(.responsive-padding) {
|
||||
@media (max-width: 768px) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
+285
-36
@@ -1,47 +1,296 @@
|
||||
<script lang="ts">
|
||||
import { WizardWithSteps } from '$lib/layout';
|
||||
import { Wizard } from '$lib/layout';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizardWithSteps.svelte';
|
||||
import Step1 from './wizard/react-native/step1.svelte';
|
||||
import Step2 from './wizard/react-native/step2.svelte';
|
||||
import Step3 from './wizard/react-native/step3.svelte';
|
||||
import Step4 from './wizard/step4.svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
import {
|
||||
Code,
|
||||
Layout,
|
||||
Icon,
|
||||
Typography,
|
||||
Fieldset,
|
||||
InlineCode,
|
||||
Spinner
|
||||
} from '@appwrite.io/pink-svelte';
|
||||
import { Button, Form, InputText } from '$lib/elements/forms';
|
||||
import { IconReact, IconAppwrite } from '@appwrite.io/pink-icons-svelte';
|
||||
import { Card } from '$lib/components';
|
||||
import { base } from '$app/paths';
|
||||
import { page } from '$app/stores';
|
||||
import { onMount } from 'svelte';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
|
||||
import { addNotification } from '$lib/stores/notifications';
|
||||
import { fade } from 'svelte/transition';
|
||||
import ConnectionLine from './components/ConnectionLine.svelte';
|
||||
import OnboardingPlatformCard from './components/OnboardingPlatformCard.svelte';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { LabelCard } from '$lib/components';
|
||||
|
||||
async function onFinish() {
|
||||
await Promise.all([invalidate(Dependencies.PROJECT), invalidate(Dependencies.PLATFORMS)]);
|
||||
let showExitModal = false;
|
||||
let isPlatformCreated = false;
|
||||
let isCreatingPlatform = false;
|
||||
let connectionSuccessful = false;
|
||||
const projectId = $page.params.project;
|
||||
|
||||
createPlatform.reset();
|
||||
wizard.hide();
|
||||
const gitCloneCode =
|
||||
'\ngit clone https://github.com/appwrite/starter-for-react-native\ncd starter-for-react-native\n';
|
||||
|
||||
const updateConfigCode = isCloud
|
||||
? `const APPWRITE_PROJECT_ID = "${projectId}";`
|
||||
: `const APPWRITE_PROJECT_ID = "${projectId}";
|
||||
const APPWRITE_PUBLIC_ENDPOINT = "${sdk.forProject.client.config.endpoint}";
|
||||
`;
|
||||
|
||||
let platform: PlatformType = PlatformType.Reactnativeandroid;
|
||||
|
||||
let platforms: { [key: string]: PlatformType } = {
|
||||
Android: PlatformType.Reactnativeandroid,
|
||||
iOS: PlatformType.Reactnativeios
|
||||
};
|
||||
|
||||
const placeholder: Partial<
|
||||
Record<
|
||||
PlatformType,
|
||||
{
|
||||
name: string;
|
||||
hostname: string;
|
||||
tooltip: string;
|
||||
}
|
||||
>
|
||||
> = {
|
||||
[PlatformType.Reactnativeandroid]: {
|
||||
name: 'My Android App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
'Your package name is generally the applicationId in your app-level build.gradle file.'
|
||||
},
|
||||
[PlatformType.Reactnativeios]: {
|
||||
name: 'My iOS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
}
|
||||
};
|
||||
|
||||
const hostname: Partial<Record<PlatformType, string>> = {
|
||||
[PlatformType.Reactnativeandroid]: 'Package Name',
|
||||
[PlatformType.Reactnativeios]: 'Bundle ID'
|
||||
};
|
||||
|
||||
async function createFlutterPlatform() {
|
||||
try {
|
||||
isCreatingPlatform = true;
|
||||
await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
isPlatformCreated = true;
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
|
||||
await Promise.all([
|
||||
invalidate(Dependencies.PROJECT),
|
||||
invalidate(Dependencies.PLATFORMS)
|
||||
]);
|
||||
} catch (error) {
|
||||
trackError(error, Submit.PlatformCreate);
|
||||
addNotification({
|
||||
type: 'error',
|
||||
message: error.message
|
||||
});
|
||||
} finally {
|
||||
isCreatingPlatform = false;
|
||||
}
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Settings',
|
||||
component: Step1
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Install',
|
||||
component: Step2,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
label: 'Import',
|
||||
component: Step3,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
label: 'Build',
|
||||
component: Step4,
|
||||
optional: true
|
||||
async function resetPlatformStore() {
|
||||
createPlatform.reset();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
const unsubscribe = sdk.forConsole.client.subscribe('console', (response) => {
|
||||
if (response.events.includes(`projects.${projectId}.ping`) && isPlatformCreated) {
|
||||
connectionSuccessful = true;
|
||||
unsubscribe();
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
unsubscribe();
|
||||
resetPlatformStore();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<WizardWithSteps
|
||||
title="Add a React Native platform"
|
||||
steps={stepsComponents}
|
||||
on:finish={onFinish}
|
||||
on:exit={onFinish}
|
||||
finalAction="Go to dashboard" />
|
||||
<Wizard title="Add React Native platform" bind:showExitModal confirmExit>
|
||||
<Form onSubmit={createFlutterPlatform}>
|
||||
<Layout.Stack gap="xxl">
|
||||
<!-- Step One -->
|
||||
<Layout.Stack gap="l" direction="row">
|
||||
{#each Object.entries(platforms) as [key, value]}
|
||||
<div class="u-width-full-line">
|
||||
<!-- TODO: https://github.com/appwrite/pink/pull/248 for correct spacing -->
|
||||
<LabelCard
|
||||
name={key}
|
||||
bind:group={platform}
|
||||
variant="primary"
|
||||
{value}
|
||||
title={key} />
|
||||
</div>
|
||||
{/each}
|
||||
</Layout.Stack>
|
||||
|
||||
<!-- Step Two -->
|
||||
{#if !isPlatformCreated}
|
||||
<Fieldset legend="Details">
|
||||
<Layout.Stack gap="l" alignItems="flex-end">
|
||||
<Layout.Stack gap="s">
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder={placeholder[platform].name}
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
|
||||
<!-- Tooltips on InputText don't work as of now -->
|
||||
<InputText
|
||||
id="hostname"
|
||||
label={hostname[platform]}
|
||||
placeholder={placeholder[platform].hostname}
|
||||
tooltip={placeholder[platform].tooltip}
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Button
|
||||
fullWidthMobile
|
||||
size="s"
|
||||
submit
|
||||
forceShowLoader
|
||||
submissionLoader={isCreatingPlatform}
|
||||
disabled={!platform ||
|
||||
!$createPlatform.name ||
|
||||
!$createPlatform.key ||
|
||||
isCreatingPlatform}>
|
||||
Create platform
|
||||
</Button>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{:else}
|
||||
<Layout.Stack gap="xxl">
|
||||
<Card isTile padding="s" radius="s">
|
||||
<Layout.Stack
|
||||
direction="row"
|
||||
justifyContent="space-between"
|
||||
alignItems="center"
|
||||
gap="xs">
|
||||
<Layout.Stack direction="row" alignItems="center" gap="s">
|
||||
<Icon size="m" icon={IconReact} />
|
||||
<Typography.Text
|
||||
variant="m-400"
|
||||
color="--color-fgcolor-neutral-primary">
|
||||
{$createPlatform.name} ({$createPlatform.key})
|
||||
</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</Layout.Stack>
|
||||
{/if}
|
||||
|
||||
<!-- Step Three -->
|
||||
{#if isPlatformCreated}
|
||||
<Fieldset legend="Clone starter">
|
||||
<Layout.Stack gap="l">
|
||||
<Typography.Text variant="m-500">
|
||||
1. Clone the starter kit from GitHub using the terminal or VSCode.
|
||||
</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="bash" lineNumbers code={gitCloneCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>2. Open the file <InlineCode
|
||||
size="s"
|
||||
code="lib/constants/appwrite.js" /> and update the configuration settings.</Typography.Text>
|
||||
|
||||
<!-- Temporary fix: Remove this div once Code splitting issue with stack spacing is resolved -->
|
||||
<div class="pink2-code-margin-fix">
|
||||
<Code lang="javascript" lineNumbers code={updateConfigCode} />
|
||||
</div>
|
||||
|
||||
<Typography.Text variant="m-500"
|
||||
>3. Run the app on a connected device or simulator, then click the <InlineCode
|
||||
size="s"
|
||||
code="Send a ping" /> button to verify the setup.</Typography.Text>
|
||||
</Layout.Stack>
|
||||
</Fieldset>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Form>
|
||||
<svelte:fragment slot="aside">
|
||||
<Card padding="l" class="responsive-padding">
|
||||
<Layout.Stack gap="xxl">
|
||||
<Layout.Stack direction="row" justifyContent="center" gap="none">
|
||||
<OnboardingPlatformCard iconSize={2.526} iconColor="#61DBFB" icon={IconReact} />
|
||||
|
||||
<ConnectionLine status={connectionSuccessful} />
|
||||
|
||||
<OnboardingPlatformCard
|
||||
iconSize={2.526}
|
||||
iconColor="#FD366E"
|
||||
icon={IconAppwrite} />
|
||||
</Layout.Stack>
|
||||
|
||||
<Layout.Stack direction="row" justifyContent="center" alignItems="center" gap="l">
|
||||
{#if !connectionSuccessful}
|
||||
<Spinner />
|
||||
<Typography.Text variant="m-400">Waiting for connection...</Typography.Text>
|
||||
{:else}
|
||||
<!-- cannot apply fade on components -->
|
||||
<div
|
||||
in:fade={{ duration: 2500 }}
|
||||
class="u-flex u-flex-vertical u-cross-center u-gap-8">
|
||||
<Typography.Title size="m">Congratulations!</Typography.Title>
|
||||
|
||||
<Typography.Text variant="m-400"
|
||||
>You connected your app successfully.</Typography.Text>
|
||||
</div>
|
||||
{/if}
|
||||
</Layout.Stack>
|
||||
</Layout.Stack>
|
||||
</Card>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<Button
|
||||
size="s"
|
||||
fullWidthMobile
|
||||
secondary
|
||||
disabled={isCreatingPlatform}
|
||||
href={`${base}/project-${projectId}/overview`}>
|
||||
Go to dashboard
|
||||
</Button>
|
||||
</svelte:fragment>
|
||||
</Wizard>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.pink2-code-margin-fix pre) {
|
||||
margin: revert;
|
||||
}
|
||||
|
||||
:global(.responsive-padding) {
|
||||
@media (max-width: 768px) {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { WizardWithSteps } from '$lib/layout';
|
||||
import { invalidate } from '$app/navigation';
|
||||
import { wizard } from '$lib/stores/wizard';
|
||||
import { createPlatform } from './wizard/store';
|
||||
import type { WizardStepsType } from '$lib/layout/wizardWithSteps.svelte';
|
||||
import Step1 from './wizard/web/step1.svelte';
|
||||
import Step2 from './wizard/web/step2.svelte';
|
||||
import Step3 from './wizard/web/step3.svelte';
|
||||
import Step4 from './wizard/step4.svelte';
|
||||
import { Dependencies } from '$lib/constants';
|
||||
|
||||
async function onFinish() {
|
||||
await Promise.all([invalidate(Dependencies.PROJECT), invalidate(Dependencies.PLATFORMS)]);
|
||||
|
||||
createPlatform.reset();
|
||||
wizard.hide();
|
||||
}
|
||||
|
||||
const stepsComponents: WizardStepsType = new Map();
|
||||
stepsComponents.set(1, {
|
||||
label: 'Settings',
|
||||
component: Step1
|
||||
});
|
||||
stepsComponents.set(2, {
|
||||
label: 'Install',
|
||||
component: Step2,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(3, {
|
||||
label: 'Import',
|
||||
component: Step3,
|
||||
optional: true
|
||||
});
|
||||
stepsComponents.set(4, {
|
||||
label: 'Build',
|
||||
component: Step4,
|
||||
optional: true
|
||||
});
|
||||
</script>
|
||||
|
||||
<WizardWithSteps
|
||||
title="Add a web platform"
|
||||
steps={stepsComponents}
|
||||
on:finish={onFinish}
|
||||
on:exit={onFinish}
|
||||
finalAction="Go to dashboard" />
|
||||
@@ -1,60 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
async function beforeSubmit() {
|
||||
if ($createPlatform.$id) {
|
||||
await sdk.forConsole.projects.updatePlatform(
|
||||
projectId,
|
||||
$createPlatform.$id,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
$createPlatform.store || undefined,
|
||||
$createPlatform.hostname || undefined
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const platform = await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
PlatformType.Android,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: 'android'
|
||||
});
|
||||
|
||||
$createPlatform.$id = platform.$id;
|
||||
}
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">Android registration</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="My Android App"
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
<InputText
|
||||
id="key"
|
||||
label="Package Name"
|
||||
placeholder="com.company.appname"
|
||||
tooltip="Your package name is generally the applicationId in your app-level build.gradle file."
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</FormList>
|
||||
</WizardStep>
|
||||
@@ -1,18 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { versions } from '../store';
|
||||
|
||||
const example1 = `repositories {
|
||||
mavenCentral()
|
||||
}`;
|
||||
const example2 = `implementation("io.appwrite:sdk-for-android:${$versions['client-android']}")`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Install</svelte:fragment>
|
||||
<p>First, add this to your root level <code class="inline-code">build.gradle</code> file.</p>
|
||||
<Code label="Groovy" labelIcon="android" language="kotlin" code={example1} withCopy />
|
||||
<p class="common-section">And add this to your project's build.gradle file.</p>
|
||||
<Code label="Groovy" labelIcon="android" language="kotlin" code={example2} withCopy />
|
||||
</WizardStep>
|
||||
@@ -1,41 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import Id from '$lib/components/id.svelte';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { isCloud } from '$lib/system';
|
||||
|
||||
const { endpoint, project } = sdk.forProject.client.config;
|
||||
const code = `import io.appwrite.Client
|
||||
import io.appwrite.services.Account
|
||||
|
||||
${
|
||||
isCloud
|
||||
? `val client = Client(context).setProject("${project}")`
|
||||
: `val client = Client(context)
|
||||
.setEndpoint("${endpoint}")
|
||||
.setProject("${project}")
|
||||
.setSelfSigned(status: true) // For self signed certificates, only use for development`
|
||||
}`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Initialize</svelte:fragment>
|
||||
|
||||
<h2 class="heading-level-7">Initialize your SDK</h2>
|
||||
<p>
|
||||
Initialize your SDK by pointing the client to your Appwrite project using your <Id
|
||||
value={project}>Project ID</Id
|
||||
>.
|
||||
</p>
|
||||
<div class="u-margin-block-start-16">
|
||||
<Code
|
||||
label="Android SDK"
|
||||
labelIcon="android"
|
||||
language="kotlin"
|
||||
{code}
|
||||
withCopy
|
||||
withLineNumbers
|
||||
noMargin />
|
||||
</div>
|
||||
</WizardStep>
|
||||
@@ -1,83 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
|
||||
let platform: PlatformType = PlatformType.Appleios;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
|
||||
async function beforeSubmit() {
|
||||
if ($createPlatform.$id) {
|
||||
await sdk.forConsole.projects.deletePlatform(projectId, $createPlatform.$id);
|
||||
}
|
||||
|
||||
const response = await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
|
||||
$createPlatform.$id = response.$id;
|
||||
$createPlatform.type = platform;
|
||||
}
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">Apple registration</svelte:fragment>
|
||||
|
||||
<FormList>
|
||||
<p>Choose an Apple platform</p>
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8">
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Appleios)}
|
||||
selected={platform === PlatformType.Appleios}>
|
||||
iOS
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Applemacos)}
|
||||
selected={platform === PlatformType.Applemacos}>
|
||||
macOS
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Applewatchos)}
|
||||
selected={platform === PlatformType.Applewatchos}>
|
||||
watchOS
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Appletvos)}
|
||||
selected={platform === PlatformType.Appletvos}>
|
||||
tvOS
|
||||
</Pill>
|
||||
</div>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="My Apple App"
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
<InputText
|
||||
id="hostname"
|
||||
label="Bundle ID"
|
||||
placeholder="com.company.appname"
|
||||
tooltip="You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</FormList>
|
||||
</WizardStep>
|
||||
@@ -1,81 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { versions } from '../store';
|
||||
|
||||
enum Method {
|
||||
Xcode,
|
||||
Swift
|
||||
}
|
||||
|
||||
let method: Method = Method.Xcode;
|
||||
|
||||
const example1 = `dependencies: [
|
||||
.package(
|
||||
name: "Appwrite",
|
||||
url: "https://github.com/appwrite/sdk-for-swift",
|
||||
.exact("${$versions['client-apple']}")
|
||||
)
|
||||
]')`;
|
||||
const example2 = `targets: [
|
||||
.target(
|
||||
name: "[YOUR_TARGET]",
|
||||
dependencies: [
|
||||
"Appwrite"
|
||||
]
|
||||
)
|
||||
]`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Install</svelte:fragment>
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8">
|
||||
<Pill button on:click={() => (method = Method.Xcode)} selected={method === Method.Xcode}>
|
||||
Xcode
|
||||
</Pill>
|
||||
<Pill button on:click={() => (method = Method.Swift)} selected={method === Method.Swift}>
|
||||
Swift Packages
|
||||
</Pill>
|
||||
</div>
|
||||
<div class="common-section">
|
||||
{#if method === Method.Xcode}
|
||||
<ol class="numeric-list">
|
||||
<li class="numeric-list-item">
|
||||
<span class="text">
|
||||
In the menu bar under Select File, select Add Packages
|
||||
</span>
|
||||
</li>
|
||||
<li class="numeric-list-item">
|
||||
<span class="text">
|
||||
Search for the Appwrite SDK with the URL
|
||||
<a class="link" href="https://github.com/appwrite/sdk-for-apple">
|
||||
https://github.com/appwrite/sdk-for-apple
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<li class="numeric-list-item">
|
||||
<span class="text"
|
||||
>In the right panel, select your target project and add your desired version
|
||||
rules</span>
|
||||
</li>
|
||||
<li class="numeric-list-item">
|
||||
<span class="text">
|
||||
Select Add Package and wait for package resolution to complete
|
||||
</span>
|
||||
</li>
|
||||
<li class="numeric-list-item">
|
||||
<span class="text">
|
||||
Make sure the Appwrite package product is checked and select Add Package
|
||||
again
|
||||
</span>
|
||||
</li>
|
||||
</ol>
|
||||
{:else if method === Method.Swift}
|
||||
<p>Add this to your <code class="inline-code">Package.swift</code> file.</p>
|
||||
<Code withCopy withLineNumbers label="Swift" language="swift" code={example1} />
|
||||
<p class="common-section">Then add the dependency to your target.</p>
|
||||
<Code withCopy withLineNumbers label="Swift" language="swift" code={example2} />
|
||||
{/if}
|
||||
</div>
|
||||
</WizardStep>
|
||||
@@ -1,48 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Alert, Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import Id from '$lib/components/id.svelte';
|
||||
|
||||
const { endpoint, project } = sdk.forProject.client.config;
|
||||
const code = `import Appwrite
|
||||
|
||||
${
|
||||
isCloud
|
||||
? `let client = Client().setProject("${project}")`
|
||||
: `let client = Client()
|
||||
.setEndpoint("${endpoint}")
|
||||
.setProject("${project}")
|
||||
.setSelfSigned(true) // For self signed certificates, only use for development`
|
||||
}`;
|
||||
|
||||
let showAlert = true;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Initialize</svelte:fragment>
|
||||
|
||||
<h2 class="heading-level-7">Initialize your SDK</h2>
|
||||
<p>
|
||||
Initialize your SDK by pointing the client to your Appwrite project using your
|
||||
<Id value={project}>Project ID</Id>
|
||||
.
|
||||
</p>
|
||||
<Code label="Apple SDK" labelIcon="apple" language="swift" {code} withCopy withLineNumbers />
|
||||
<p class="u-margin-block-start-24">
|
||||
Before sending any API calls to your new Appwrite project, make sure your device or emulator
|
||||
has network access to your Appwrite project's hostname or IP address.
|
||||
</p>
|
||||
{#if showAlert && !isCloud}
|
||||
<div class="common-section">
|
||||
<Alert type="info" dismissible on:dismiss={() => (showAlert = false)}>
|
||||
<svelte:fragment slot="title">For self-hosted solutions</svelte:fragment>
|
||||
When connecting to a locally hosted Appwrite project from an emulator or a mobile device,
|
||||
you should use the private IP of the device running your Appwrite project as the hostname
|
||||
of the endpoint instead of localhost. You can also use a service like ngrok to proxy
|
||||
the Appwrite server.
|
||||
</Alert>
|
||||
</div>
|
||||
{/if}
|
||||
</WizardStep>
|
||||
-199
@@ -1,199 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types';
|
||||
|
||||
// enum Platform {
|
||||
// Android = 'flutter-android',
|
||||
// Ios = 'flutter-ios',
|
||||
// Linux = 'flutter-linux',
|
||||
// Macos = 'flutter-macos',
|
||||
// Windows = 'flutter-windows',
|
||||
// Web = 'flutter-web'
|
||||
// }
|
||||
|
||||
// function isPlatform(value: string): value is Platform {
|
||||
// return Object.values(Platform).includes(value as Platform);
|
||||
// }
|
||||
|
||||
let platform: PlatformType = isValueOfStringEnum(PlatformType, $createPlatform.type)
|
||||
? $createPlatform.type
|
||||
: PlatformType.Flutterandroid;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.io'];
|
||||
const placeholder: Partial<
|
||||
Record<
|
||||
PlatformType,
|
||||
{
|
||||
name: string;
|
||||
hostname: string;
|
||||
tooltip: string;
|
||||
}
|
||||
>
|
||||
> = {
|
||||
[PlatformType.Flutterandroid]: {
|
||||
name: 'My Android App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
'Your package name is generally the applicationId in your app-level build.gradle file.'
|
||||
},
|
||||
[PlatformType.Flutterios]: {
|
||||
name: 'My iOS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
},
|
||||
[PlatformType.Flutterlinux]: {
|
||||
name: 'My Linux App',
|
||||
hostname: 'appname',
|
||||
tooltip: 'Your application name'
|
||||
},
|
||||
[PlatformType.Fluttermacos]: {
|
||||
name: 'My mac OS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
},
|
||||
[PlatformType.Flutterweb]: {
|
||||
name: 'My Web App',
|
||||
hostname: 'localhost',
|
||||
tooltip:
|
||||
'The hostname that your website will use to interact with the Appwrite APIs in production or development environments. No protocol or port number required.'
|
||||
},
|
||||
[PlatformType.Flutterwindows]: {
|
||||
name: 'My Windows App',
|
||||
hostname: 'appname',
|
||||
tooltip: 'Your application name'
|
||||
}
|
||||
};
|
||||
|
||||
const hostname: Partial<Record<PlatformType, string>> = {
|
||||
[PlatformType.Flutterandroid]: 'Package Name',
|
||||
[PlatformType.Flutterios]: 'Bundle ID',
|
||||
[PlatformType.Flutterlinux]: 'Package Name',
|
||||
[PlatformType.Fluttermacos]: 'Bundle ID',
|
||||
[PlatformType.Flutterweb]: 'Hostname',
|
||||
[PlatformType.Flutterwindows]: 'Package Name'
|
||||
};
|
||||
|
||||
async function beforeSubmit() {
|
||||
if ($createPlatform.$id) {
|
||||
await sdk.forConsole.projects.deletePlatform(projectId, $createPlatform.$id);
|
||||
}
|
||||
|
||||
const response = await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
platform !== PlatformType.Flutterweb ? $createPlatform.key : undefined,
|
||||
undefined,
|
||||
platform === PlatformType.Flutterweb ? $createPlatform.hostname : undefined
|
||||
);
|
||||
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
|
||||
$createPlatform.$id = response.$id;
|
||||
$createPlatform.type = platform;
|
||||
}
|
||||
|
||||
$: registee = {
|
||||
[PlatformType.Flutterandroid]: 'Package name',
|
||||
[PlatformType.Flutterios]: 'Bundle ID',
|
||||
[PlatformType.Flutterlinux]: 'Package name',
|
||||
[PlatformType.Fluttermacos]: 'Bundle ID',
|
||||
[PlatformType.Flutterwindows]: 'Package name',
|
||||
[PlatformType.Flutterweb]: 'Hostname'
|
||||
}[platform];
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">{registee} registration</svelte:fragment>
|
||||
<svelte:fragment slot="subtitle">
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8 u-flex-wrap">
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Flutterandroid)}
|
||||
selected={platform === PlatformType.Flutterandroid}>
|
||||
Android
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Flutterios)}
|
||||
selected={platform === PlatformType.Flutterios}>
|
||||
iOS
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Flutterlinux)}
|
||||
selected={platform === PlatformType.Flutterlinux}>
|
||||
Linux
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Fluttermacos)}
|
||||
selected={platform === PlatformType.Fluttermacos}>
|
||||
macOS
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Flutterwindows)}
|
||||
selected={platform === PlatformType.Flutterwindows}>
|
||||
Windows
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Flutterweb)}
|
||||
selected={platform === PlatformType.Flutterweb}>
|
||||
Web
|
||||
</Pill>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<FormList isCommonSection>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder={placeholder[platform].name}
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
{#if platform === PlatformType.Flutterweb}
|
||||
<div>
|
||||
<InputText
|
||||
id="hostname"
|
||||
label={hostname[platform]}
|
||||
placeholder={placeholder[platform].hostname}
|
||||
tooltip={placeholder[platform].tooltip}
|
||||
required
|
||||
bind:value={$createPlatform.hostname} />
|
||||
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8">
|
||||
{#each suggestions as suggestion}
|
||||
<Pill
|
||||
button
|
||||
selected={$createPlatform.hostname === suggestion}
|
||||
on:click={() => ($createPlatform.hostname = suggestion)}>
|
||||
{suggestion}
|
||||
</Pill>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<InputText
|
||||
id="key"
|
||||
label={hostname[platform]}
|
||||
placeholder={placeholder[platform].hostname}
|
||||
tooltip={placeholder[platform].tooltip}
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
{/if}
|
||||
</FormList>
|
||||
</WizardStep>
|
||||
@@ -1,25 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { versions } from '../store';
|
||||
|
||||
const example1 = `dependencies:
|
||||
appwrite: ^${$versions['client-flutter']}`;
|
||||
const example2 = `flutter pub add appwrite`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Install</svelte:fragment>
|
||||
|
||||
<p>
|
||||
Add Appwrite SDK to your package's <code class="inline-code">pubspec.yaml</code> file. You can
|
||||
view an example here.
|
||||
</p>
|
||||
<Code label="YAML" language="yml" code={example1} withCopy />
|
||||
<p class="common-section">
|
||||
You can also install the SDK using the Dart package manager from your terminal.
|
||||
</p>
|
||||
<div class="u-margin-block-start-16">
|
||||
<Code label="Bash" language="sh" code={example2} withCopy noMargin />
|
||||
</div>
|
||||
</WizardStep>
|
||||
@@ -1,57 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Alert, Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import Id from '$lib/components/id.svelte';
|
||||
|
||||
const { endpoint, project } = sdk.forProject.client.config;
|
||||
const code = `import 'package:appwrite/appwrite.dart';
|
||||
|
||||
Client client = Client();
|
||||
${
|
||||
isCloud
|
||||
? `client.setProject('${project}');`
|
||||
: `client
|
||||
.setEndpoint('${endpoint}')
|
||||
.setProject('${project}')
|
||||
.setSelfSigned(status: true); // For self signed certificates, only use for development;`
|
||||
}`;
|
||||
|
||||
let showAlert = true;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Initialize</svelte:fragment>
|
||||
|
||||
<h2 class="heading-level-7">Initialize your SDK</h2>
|
||||
<p data-private>
|
||||
Initialize your SDK by pointing the client to your Appwrite project using your
|
||||
<Id value={project}>Project ID</Id>
|
||||
</p>
|
||||
<div class="u-margin-block-start-16">
|
||||
<Code
|
||||
label="Flutter SDK"
|
||||
labelIcon="flutter"
|
||||
language="dart"
|
||||
{code}
|
||||
withCopy
|
||||
withLineNumbers
|
||||
noMargin />
|
||||
</div>
|
||||
<p class="common-section">
|
||||
Before sending any API calls to your new Appwrite project, make sure your device or emulator
|
||||
has network access to your Appwrite project's hostname or IP address.
|
||||
</p>
|
||||
{#if showAlert && !isCloud}
|
||||
<div class="common-section">
|
||||
<Alert type="info" on:dismiss={() => (showAlert = false)}>
|
||||
<svelte:fragment slot="title">For self-hosted solutions</svelte:fragment>
|
||||
When connecting to a locally hosted Appwrite project from an emulator or a mobile device,
|
||||
you should use the private IP of the device running your Appwrite project as the hostname
|
||||
of the endpoint instead of localhost. You can also use a service like ngrok to proxy
|
||||
the Appwrite server.
|
||||
</Alert>
|
||||
</div>
|
||||
{/if}
|
||||
</WizardStep>
|
||||
-106
@@ -1,106 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
import { isValueOfStringEnum } from '$lib/helpers/types';
|
||||
|
||||
let platform: PlatformType = isValueOfStringEnum(PlatformType, $createPlatform.type)
|
||||
? $createPlatform.type
|
||||
: PlatformType.Reactnativeandroid;
|
||||
|
||||
const projectId = $page.params.project;
|
||||
const placeholder: Partial<
|
||||
Record<
|
||||
PlatformType,
|
||||
{
|
||||
name: string;
|
||||
hostname: string;
|
||||
tooltip: string;
|
||||
}
|
||||
>
|
||||
> = {
|
||||
[PlatformType.Reactnativeandroid]: {
|
||||
name: 'My Android App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
'Your package name is generally the applicationId in your app-level build.gradle file.'
|
||||
},
|
||||
[PlatformType.Reactnativeios]: {
|
||||
name: 'My iOS App',
|
||||
hostname: 'com.company.appname',
|
||||
tooltip:
|
||||
"You can find your Bundle Identifier in the General tab for your app's primary target in Xcode."
|
||||
}
|
||||
};
|
||||
|
||||
const hostname: Partial<Record<PlatformType, string>> = {
|
||||
[PlatformType.Reactnativeandroid]: 'Package Name',
|
||||
[PlatformType.Reactnativeios]: 'Bundle ID'
|
||||
};
|
||||
|
||||
async function beforeSubmit() {
|
||||
if ($createPlatform.$id) {
|
||||
await sdk.forConsole.projects.deletePlatform(projectId, $createPlatform.$id);
|
||||
}
|
||||
|
||||
const response = await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
platform,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key
|
||||
);
|
||||
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: platform
|
||||
});
|
||||
|
||||
$createPlatform.$id = response.$id;
|
||||
$createPlatform.type = platform;
|
||||
}
|
||||
|
||||
$: registee = {
|
||||
[PlatformType.Reactnativeandroid]: 'Package name',
|
||||
[PlatformType.Reactnativeios]: 'Bundle ID'
|
||||
}[platform];
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">{registee} registration</svelte:fragment>
|
||||
<svelte:fragment slot="subtitle">
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8 u-flex-wrap">
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Reactnativeandroid)}
|
||||
selected={platform === PlatformType.Reactnativeandroid}>
|
||||
Android
|
||||
</Pill>
|
||||
<Pill
|
||||
button
|
||||
on:click={() => (platform = PlatformType.Reactnativeios)}
|
||||
selected={platform === PlatformType.Reactnativeios}>
|
||||
iOS
|
||||
</Pill>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<FormList isCommonSection>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder={placeholder[platform].name}
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
<InputText
|
||||
id="key"
|
||||
label={hostname[platform]}
|
||||
placeholder={placeholder[platform].hostname}
|
||||
tooltip={placeholder[platform].tooltip}
|
||||
required
|
||||
bind:value={$createPlatform.key} />
|
||||
</FormList>
|
||||
</WizardStep>
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
|
||||
const example = `npx expo install react-native-appwrite react-native-url-polyfill`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Install</svelte:fragment>
|
||||
|
||||
<p>Install the Appwrite SDK for React Native and required dependencies.</p>
|
||||
<Code label="Bash" language="sh" code={example} withCopy />
|
||||
</WizardStep>
|
||||
-58
@@ -1,58 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Alert, Code } from '$lib/components';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { isCloud } from '$lib/system';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import Id from '$lib/components/id.svelte';
|
||||
|
||||
const { endpoint, project } = sdk.forProject.client.config;
|
||||
const code = `import { Client, Account, ID } from 'react-native-appwrite';
|
||||
|
||||
const client = new Client()${
|
||||
isCloud
|
||||
? ''
|
||||
: `
|
||||
.setEndpoint('${endpoint}')`
|
||||
}
|
||||
.setProject('${project}')
|
||||
.setPlatform('${$createPlatform.key}');
|
||||
`;
|
||||
|
||||
let showAlert = true;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Initialize</svelte:fragment>
|
||||
|
||||
<h2 class="heading-level-7">Initialize your SDK</h2>
|
||||
<p data-private>
|
||||
Initialize your SDK by pointing the client to your Appwrite project using your <Id
|
||||
value={project}>Project ID</Id>
|
||||
</p>
|
||||
<div class="u-margin-block-start-16">
|
||||
<Code
|
||||
label="React Native"
|
||||
labelIcon="code"
|
||||
language="js"
|
||||
{code}
|
||||
withCopy
|
||||
withLineNumbers
|
||||
noMargin />
|
||||
</div>
|
||||
<p class="common-section">
|
||||
Before sending any API calls to your new Appwrite project, make sure your device or emulator
|
||||
has network access to your Appwrite project's hostname or IP address.
|
||||
</p>
|
||||
{#if showAlert && !isCloud}
|
||||
<div class="common-section">
|
||||
<Alert type="info" on:dismiss={() => (showAlert = false)}>
|
||||
<svelte:fragment slot="title">For self-hosted solutions</svelte:fragment>
|
||||
When connecting to a locally hosted Appwrite project from an emulator or a mobile device,
|
||||
you should use the private IP of the device running your Appwrite project as the hostname
|
||||
of the endpoint instead of localhost. You can also use a service like ngrok to proxy
|
||||
the Appwrite server.
|
||||
</Alert>
|
||||
</div>
|
||||
{/if}
|
||||
</WizardStep>
|
||||
@@ -1,84 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { Alert } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { FormList, InputText } from '$lib/elements/forms';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { createPlatform } from '../store';
|
||||
import { Submit, trackEvent } from '$lib/actions/analytics';
|
||||
import { PlatformType } from '@appwrite.io/console';
|
||||
|
||||
const projectId = $page.params.project;
|
||||
const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.io'];
|
||||
|
||||
async function beforeSubmit() {
|
||||
if ($createPlatform.$id) {
|
||||
await sdk.forConsole.projects.updatePlatform(
|
||||
projectId,
|
||||
$createPlatform.$id,
|
||||
$createPlatform.name,
|
||||
$createPlatform.key || undefined,
|
||||
$createPlatform.store || undefined,
|
||||
$createPlatform.hostname || undefined
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const platform = await sdk.forConsole.projects.createPlatform(
|
||||
projectId,
|
||||
PlatformType.Web,
|
||||
$createPlatform.name,
|
||||
undefined,
|
||||
undefined,
|
||||
$createPlatform.hostname || undefined
|
||||
);
|
||||
|
||||
trackEvent(Submit.PlatformCreate, {
|
||||
type: 'web'
|
||||
});
|
||||
|
||||
$createPlatform.$id = platform.$id;
|
||||
}
|
||||
</script>
|
||||
|
||||
<WizardStep {beforeSubmit}>
|
||||
<svelte:fragment slot="title">Hostname registration</svelte:fragment>
|
||||
<FormList>
|
||||
<InputText
|
||||
id="name"
|
||||
label="Name"
|
||||
placeholder="My Web App"
|
||||
required
|
||||
bind:value={$createPlatform.name} />
|
||||
<div>
|
||||
<InputText
|
||||
id="hostname"
|
||||
label="Hostname"
|
||||
placeholder="localhost"
|
||||
tooltip="The hostname that your website will use to interact with the Appwrite APIs in production or development environments. No protocol or port number required."
|
||||
required
|
||||
bind:value={$createPlatform.hostname} />
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8">
|
||||
{#each suggestions as suggestion}
|
||||
<Pill
|
||||
button
|
||||
selected={$createPlatform.hostname === suggestion}
|
||||
on:click={() => ($createPlatform.hostname = suggestion)}>
|
||||
{suggestion}
|
||||
</Pill>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
<Alert type="warning">
|
||||
Using wildcard hostnames in production can become insecure. You can read about
|
||||
<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="link">
|
||||
Cross-Origin Resource Sharing (CORS)</a> for more information.
|
||||
</Alert>
|
||||
</FormList>
|
||||
</WizardStep>
|
||||
@@ -1,64 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { versions } from '../store';
|
||||
|
||||
import { Code } from '$lib/components';
|
||||
import { Pill } from '$lib/elements';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
|
||||
enum Method {
|
||||
NPM,
|
||||
CDN
|
||||
}
|
||||
|
||||
let method: Method = Method.NPM;
|
||||
|
||||
const example1 = `import { Client } from 'appwrite';`;
|
||||
const example2 =
|
||||
`<script src="https://cdn.jsdelivr.net/npm/appwrite@${$versions['client-web']}"></script` +
|
||||
`>\n` +
|
||||
`<script>
|
||||
const { Client } = Appwrite;
|
||||
</script` +
|
||||
`>`; // Prevent svelte from processing the closing script tag
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Install</svelte:fragment>
|
||||
<svelte:fragment slot="subtitle">
|
||||
Choose your preferred method of installation
|
||||
<div class="u-flex u-gap-16 u-margin-block-start-8">
|
||||
<Pill button on:click={() => (method = Method.NPM)} selected={method === Method.NPM}>
|
||||
NPM
|
||||
</Pill>
|
||||
<Pill button on:click={() => (method = Method.CDN)} selected={method === Method.CDN}>
|
||||
CDN
|
||||
</Pill>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
{#if method === Method.NPM}
|
||||
<p>
|
||||
Use <a
|
||||
href="https://npmjs.com/package/appwrite"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="link">NPM (node package manager)</a> from your command line to add Appwrite SDK
|
||||
to your project.
|
||||
</p>
|
||||
<Code label="Bash" language="sh" code="npm install appwrite" withCopy />
|
||||
<p class="common-section">
|
||||
If you're using a bundler like <a
|
||||
href="https://vitejs.dev"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="link">Vite</a>
|
||||
or
|
||||
<a href="https://rollupjs.org" target="_blank" rel="noopener noreferrer" class="link"
|
||||
>Rollup</a
|
||||
>, import Appwrite as a module.
|
||||
</p>
|
||||
<Code label="Web SDK" labelIcon="code" language="js" code={example1} withCopy />
|
||||
{:else if method === Method.CDN}
|
||||
<p>Add the following script tags to install Appwrite with a CDN.</p>
|
||||
<Code label="HTML" language="html" code={example2} withCopy />
|
||||
{/if}
|
||||
</WizardStep>
|
||||
@@ -1,38 +0,0 @@
|
||||
<script lang="ts">
|
||||
import { Code } from '$lib/components';
|
||||
import Id from '$lib/components/id.svelte';
|
||||
import { WizardStep } from '$lib/layout';
|
||||
import { sdk } from '$lib/stores/sdk';
|
||||
import { isCloud } from '$lib/system';
|
||||
|
||||
const { endpoint, project } = sdk.forProject.client.config;
|
||||
const code = `const client = new Client();
|
||||
${
|
||||
isCloud
|
||||
? `client.setProject('${project}');`
|
||||
: `client
|
||||
.setEndpoint('${endpoint}')
|
||||
.setProject('${project}');`
|
||||
}`;
|
||||
</script>
|
||||
|
||||
<WizardStep>
|
||||
<svelte:fragment slot="title">Initialize SDK</svelte:fragment>
|
||||
|
||||
<h2 class="heading-level-7">Initialize your SDK</h2>
|
||||
<p>
|
||||
Initialize your SDK by pointing the client to your Appwrite project using your <Id
|
||||
value={project}>Project ID</Id
|
||||
>.
|
||||
</p>
|
||||
<div class="u-margin-block-start-16">
|
||||
<Code
|
||||
label="Web SDK"
|
||||
labelIcon="code"
|
||||
language="js"
|
||||
{code}
|
||||
withCopy
|
||||
withLineNumbers
|
||||
noMargin />
|
||||
</div>
|
||||
</WizardStep>
|
||||
Reference in New Issue
Block a user