Skip to content
This repository was archived by the owner on Feb 3, 2026. It is now read-only.

Commit 1bb0ab1

Browse files
authored
Merge pull request #33 from micahlt/master
Design improvements, loves, and favorites
2 parents 4272aa4 + 8a426c9 commit 1bb0ab1

13 files changed

Lines changed: 499 additions & 20120 deletions

File tree

android/app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ android {
77
minSdkVersion rootProject.ext.minSdkVersion
88
targetSdkVersion rootProject.ext.targetSdkVersion
99
versionCode 10
10-
versionName "0.7.0"
10+
versionName "0.7.4"
1111
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
1212
}
1313
buildTypes {

android/app/src/main/java/org/scratchclient4/itchy/MainActivity.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import android.content.res.Configuration;
1010
import com.getcapacitor.BridgeActivity;
1111
import com.getcapacitor.Plugin;
12+
import com.getcapacitor.plugin.http.Http;
1213

1314
import java.util.ArrayList;
1415

@@ -20,6 +21,7 @@ public void onCreate(Bundle savedInstanceState) {
2021
this.init(savedInstanceState, new ArrayList<Class<? extends Plugin>>() {{
2122
// Additional plugins you've installed go here
2223
// Ex: add(TotallyAwesomePlugin.class);
24+
add(Http.class);
2325
}});
2426
int nightModeFlags = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
2527
WebSettings webSettings = this.bridge.getWebView().getSettings();

package-lock.json

Lines changed: 122 additions & 20037 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "itchy-ionic",
3-
"version": "0.6.2",
3+
"version": "0.7.4",
44
"private": true,
55
"scripts": {
66
"serve": "vue-cli-service serve",
@@ -30,7 +30,7 @@
3030
"cordova-webintent": "github:cordova-misc/cordova-webintent",
3131
"core-js": "^3.6.5",
3232
"ionicons": "^5.5.1",
33-
"node-html-parser": "^3.2.0",
33+
"node-html-parser": "^3.3.4",
3434
"node-vibrant": "^3.1.6",
3535
"vague-time": "^2.4.2",
3636
"vue": "^3.0.5",

src/components/AuthModal.vue

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,17 @@
1414
<ion-grid>
1515
<ion-row>
1616
<ion-col style="text-align:center;">
17-
<ion-icon :icon="personCircleOutline" style="font-size: 5em;color: var(---ion-color-primary-tint)"></ion-icon>
17+
<img src="../../resources/android/icon.png" alt="Itchy Login" class="center-image">
1818
</ion-col>
1919
</ion-row>
2020
</ion-grid>
2121
<ion-item>
22-
<ion-label position="floating">Username</ion-label>
22+
<ion-label position="floating">Scratch Username</ion-label>
2323
<ion-input type="text" required v-model="username"></ion-input>
2424
</ion-item>
2525
<ion-item>
2626
<ion-label position="floating">Password</ion-label>
27-
<ion-input type="password" required v-model="password"></ion-input>
27+
<ion-input type="password" required v-model="password" @keyup.enter="logIn"></ion-input>
2828
</ion-item>
2929
<ion-grid>
3030
<ion-row>
@@ -34,7 +34,7 @@
3434
<ion-spinner v-if="loading" style="height:1.2em;margin-right:5px"></ion-spinner>
3535
<ion-label>Sign In</ion-label>
3636
</ion-button>
37-
<span style="font-size:11px;margin-top:10px;">Your data will be securely sent to our servers.</span>
37+
<div class="disclaimer">Your data will be redirected from our servers to Scratch. See our <a href="#">Privacy Policy</a> for more info.</div>
3838
</ion-col>
3939
</ion-row>
4040
</ion-grid>
@@ -45,6 +45,10 @@
4545
</template>
4646

4747
<script>
48+
/*
49+
import {
50+
parse
51+
} from 'node-html-parser'; */
4852
import {
4953
IonContent,
5054
IonHeader,
@@ -61,7 +65,8 @@ import {
6165
alertController,
6266
IonGrid,
6367
IonRow,
64-
IonCol
68+
IonCol,
69+
IonIcon
6570
} from '@ionic/vue';
6671
import {
6772
lockClosed,
@@ -99,7 +104,8 @@ export default defineComponent({
99104
IonCardContent,
100105
IonGrid,
101106
IonRow,
102-
IonCol
107+
IonCol,
108+
IonIcon
103109
},
104110
setup() {
105111
return {
@@ -133,7 +139,6 @@ export default defineComponent({
133139
}),
134140
method: "POST"
135141
});
136-
137142
if (response.status == 200) {
138143
let json = await response.json();
139144
window.localStorage.setItem("session", JSON.stringify(json));
@@ -145,9 +150,25 @@ export default defineComponent({
145150
);
146151
}
147152
}
148-
149153
this.loading = false;
150154
}
151155
}
152156
});
153157
</script>
158+
<style scoped>
159+
.disclaimer {
160+
font-size: 11px;
161+
margin-top: 10px;
162+
line-height: 12px;
163+
}
164+
165+
.disclaimer a {
166+
text-decoration: none;
167+
}
168+
169+
.center-image {
170+
border-radius: 100%;
171+
height: 10vh;
172+
width: 10vh;
173+
}
174+
</style>

src/components/ProjectModal.vue

Lines changed: 172 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<ion-toolbar>
55
<ion-buttons>
66
<ion-back-button default-href="explore" @click="closeModal"></ion-back-button>
7-
<ion-title>{{ title }}</ion-title>
7+
<ion-title>{{ title }} :D</ion-title>
88
</ion-buttons>
99
</ion-toolbar>
1010
</ion-header>
@@ -33,12 +33,34 @@
3333
</ion-card-content>
3434
</ion-card>
3535
<br />
36+
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
37+
<ion-fab-button>
38+
<ion-icon :icon="addOutline"></ion-icon>
39+
</ion-fab-button>
40+
<ion-fab-list side="top">
41+
<ion-fab-button @click="openInBrowser" data-desc="Open in Browser">
42+
<ion-icon :icon="exitOutline"></ion-icon>
43+
</ion-fab-button>
44+
<ion-fab-button @click="favorite" :data-desc="favText">
45+
<ion-icon :icon="favIcon"></ion-icon>
46+
</ion-fab-button>
47+
<ion-fab-button @click="love" :data-desc="loveText">
48+
<ion-icon :icon="loveIcon"></ion-icon>
49+
</ion-fab-button>
50+
</ion-fab-list>
51+
</ion-fab>
3652
</ion-content>
3753
</ion-page>
3854
</template>
3955

4056
<script>
41-
const axios = require('axios');
57+
import '@capacitor-community/http';
58+
import {
59+
Plugins
60+
} from '@capacitor/core';
61+
const {
62+
Http
63+
} = Plugins;
4264
const utils = require('../utils.js');
4365
import {
4466
IonContent,
@@ -50,8 +72,17 @@ import {
5072
modalController,
5173
IonCard,
5274
IonCardContent,
53-
IonRippleEffect
75+
IonRippleEffect,
76+
IonIcon
5477
} from '@ionic/vue';
78+
import {
79+
addOutline,
80+
exitOutline,
81+
heartOutline,
82+
starOutline,
83+
star,
84+
heart
85+
} from 'ionicons/icons';
5586
import {
5687
defineComponent
5788
} from 'vue';
@@ -67,12 +98,19 @@ export default defineComponent({
6798
},
6899
data() {
69100
return {
101+
session: JSON.parse(window.localStorage.getItem('session')) ? JSON.parse(window.localStorage.getItem('session'))[0] : null,
70102
title: 'loading...',
71103
author: '',
72104
content: '',
73105
instructions: 'loading...',
74106
credits: '',
75-
pfp: 'https://u.cubeupload.com/darkness3560/newscratchavataropti.png'
107+
pfp: 'https://u.cubeupload.com/darkness3560/newscratchavataropti.png',
108+
addOutline,
109+
exitOutline,
110+
favIcon: starOutline,
111+
favText: 'Favorite',
112+
loveIcon: heartOutline,
113+
loveText: 'Love'
76114
}
77115
},
78116
components: {
@@ -84,25 +122,54 @@ export default defineComponent({
84122
IonBackButton,
85123
IonCard,
86124
IonCardContent,
87-
IonRippleEffect
125+
IonRippleEffect,
126+
IonIcon
88127
},
89128
mounted() {
129+
console.log(`Session`);
130+
console.log(this.session);
90131
this.loadProject();
91132
},
92133
methods: {
93134
closeModal() {
94135
modalController.dismiss();
95136
},
96137
loadProject() {
97-
axios
98-
.get(`https://itchy-api.vercel.app/api/project?id=${this.id}`)
138+
Http.request({
139+
method: 'GET',
140+
url: `https://api.scratch.mit.edu/projects/${this.id}`
141+
})
99142
.then((response) => {
100143
this.instructions = utils.prepareText(response.data.instructions);
101144
this.credits = utils.prepareText(response.data.description);
102145
this.pfp = response.data.author.profile.images["90x90"];
103146
this.title = response.data.title;
104147
this.author = response.data.author.username;
105-
})
148+
});
149+
Http.request({
150+
method: 'GET',
151+
url: `https://api.scratch.mit.edu/projects/${this.id}/favorites/user/${this.session.username}`,
152+
headers: {
153+
"x-token": this.session.token
154+
}
155+
}).then((response) => {
156+
if (response.data.userFavorite) {
157+
this.favIcon = star;
158+
this.favText = 'Unfavorite';
159+
}
160+
});
161+
Http.request({
162+
method: 'GET',
163+
url: `https://api.scratch.mit.edu/projects/${this.id}/loves/user/${this.session.username}`,
164+
headers: {
165+
"x-token": this.session.token
166+
}
167+
}).then((response) => {
168+
if (response.data.userLove) {
169+
this.loveIcon = heart;
170+
this.loveText = 'Unlove';
171+
}
172+
});
106173
},
107174
async openAuthor() {
108175
const modal = await modalController
@@ -116,8 +183,105 @@ export default defineComponent({
116183
this.closeModal();
117184
return modal.present();
118185
},
186+
openInBrowser() {
187+
window.open(`https://scratch.mit.edu/projects/${this.id}`);
188+
},
189+
favorite() {
190+
Http.request({
191+
method: 'GET',
192+
url: `https://api.scratch.mit.edu/projects/${this.id}/favorites/user/${this.session.username}`,
193+
headers: {
194+
"x-token": this.session.token
195+
}
196+
}).then((response) => {
197+
if (response.data.userFavorite) {
198+
Http.request({
199+
method: 'DELETE',
200+
url: `https://api.scratch.mit.edu/projects/${this.id}/favorites/user/${this.session.username}`,
201+
headers: {
202+
"x-token": this.session.token
203+
}
204+
}).then((res) => {
205+
if (res.status == 200) {
206+
this.favIcon = starOutline;
207+
this.favText = 'Favorite';
208+
}
209+
})
210+
} else {
211+
Http.request({
212+
method: 'POST',
213+
url: `https://api.scratch.mit.edu/projects/${this.id}/favorites/user/${this.session.username}`,
214+
headers: {
215+
"x-token": this.session.token
216+
}
217+
}).then((res) => {
218+
if (res.status == 200) {
219+
this.favIcon = star;
220+
this.favText = 'Unfavorite';
221+
}
222+
});
223+
}
224+
});
225+
},
226+
love() {
227+
Http.request({
228+
method: 'GET',
229+
url: `https://api.scratch.mit.edu/projects/${this.id}/loves/user/${this.session.username}`,
230+
headers: {
231+
"x-token": this.session.token
232+
}
233+
}).then((response) => {
234+
if (response.data.userFavorite) {
235+
Http.request({
236+
method: 'DELETE',
237+
url: `https://api.scratch.mit.edu/projects/${this.id}/loves/user/${this.session.username}`,
238+
headers: {
239+
"x-token": this.session.token
240+
}
241+
}).then((res) => {
242+
if (res.status == 200) {
243+
this.loveIcon = heartOutline;
244+
this.loveText = 'Love';
245+
}
246+
});
247+
} else {
248+
Http.request({
249+
method: 'POST',
250+
url: `https://api.scratch.mit.edu/projects/${this.id}/loves/user/${this.session.username}`,
251+
headers: {
252+
"x-token": this.session.token
253+
}
254+
}).then((res) => {
255+
if (res.status == 200) {
256+
this.loveIcon = heart;
257+
this.loveText = 'Unlove';
258+
}
259+
});
260+
}
261+
});
262+
}
119263
}
120264
});
121265
</script>
122266
<style scoped>
267+
ion-fab {
268+
transform: translateY(-56px);
269+
}
270+
271+
ion-fab-button[data-desc] {
272+
position: relative;
273+
}
274+
275+
ion-fab-button[data-desc]::after {
276+
position: absolute;
277+
content: attr(data-desc);
278+
z-index: 1;
279+
right: 55px;
280+
bottom: 4px;
281+
background-color: var(--ion-color-light);
282+
padding: 9px;
283+
border-radius: 5px;
284+
color: var(--ion-text-color);
285+
box-shadow: 0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);
286+
}
123287
</style>

0 commit comments

Comments
 (0)