big websocket change
This commit is contained in:
1 parent
0e3c272adc
commit
73248f7d9f
12 files changed
+126
-99
No files matched your search
@@ -1,35 +0,0 @@
|
||||
import { h } from 'preact';
|
||||
import { ExternalLink, Check } from 'react-feather';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
import http from '../http';
|
||||
|
||||
export default function Offer(offer) {
|
||||
const { want: { data: details } } = offer;
|
||||
|
||||
const [accepted, setAccepted] = useState(offer.status !== 'pending');
|
||||
|
||||
async function onClick() {
|
||||
const [error] = await http.postOfferAccept(offer.id);
|
||||
if (error) return false;
|
||||
setAccepted(true);
|
||||
}
|
||||
|
||||
const classes = `${accepted ? 'accepted' : ''}`;
|
||||
const btnText = accepted
|
||||
? offer.status
|
||||
: 'Accept';
|
||||
|
||||
return (
|
||||
<div class="offer">
|
||||
<section>
|
||||
<h2>{details.artists_sort} - {details.title} <a href={details.uri} target="_blank"><ExternalLink /></a></h2>
|
||||
<h5 class='alt-text' >{details.year}</h5>
|
||||
<h5 class='alt-text'>{details.formats[0].descriptions.join(' ')}</h5>
|
||||
<h5 class='number'>${offer.total}</h5>
|
||||
</section>
|
||||
<img src={details.thumb} />
|
||||
<button onClick={onClick} disabled={accepted} class={classes} >{btnText}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -41,17 +41,8 @@ export default function Bundle(bundle) {
|
||||
const initialState = { checkedIds: bundle.items.map(i => i.id) }
|
||||
const [state, dispatch] = useReducer(reducer, initialState)
|
||||
|
||||
const [shipping, setShipping] = useState(0);
|
||||
const [baseShipping, setBaseShipping] = useState(0);
|
||||
|
||||
const items = bundle.items.map(item => Item(item, state, dispatch));
|
||||
|
||||
async function submit(e) {
|
||||
e.preventDefault();
|
||||
const [error, offers] = await http.postOffers(state.checkedIds, shipping, baseShipping);
|
||||
console.log(error, offers);
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="bundle">
|
||||
<section>
|
||||
@@ -59,23 +50,6 @@ export default function Bundle(bundle) {
|
||||
<h3>{bundle.items.length} items - {bundle.total.toFixed(2)} {bundle.currency}</h3>
|
||||
<h4>Ships: {bundle.mentionsAustralia && 'AU'} {bundle.mentionsWorldwide && 'WORLD'}</h4>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<form action="">
|
||||
<div class="item">
|
||||
<label for="shipping">Full Shipping Cost</label>
|
||||
<input type="number" name="shipping" id="shipping" value={shipping} onChange={(e) => setShipping(Number.parseFloat((e.target as HTMLInputElement).value))} step="0.01" min="0" required />
|
||||
</div>
|
||||
<div class="item">
|
||||
<label for="baseShipping">Base Shipping Cost</label>
|
||||
<input type="number" name="baseShipping" id="baseShipping" value={baseShipping} onChange={(e) => setBaseShipping(Number.parseFloat((e.target as HTMLInputElement).value))} step="0.01" min="0" required />
|
||||
</div>
|
||||
<div class="item">
|
||||
<input type="submit" value="Generate Offers" onClick={(e) => submit(e)} />
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<div class='items'>
|
||||
{items}
|
||||
</div>
|
||||
|
||||
@@ -2,24 +2,30 @@ import { h } from 'preact';
|
||||
import { ExternalLink, Check } from 'react-feather';
|
||||
import { useState } from 'preact/hooks';
|
||||
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { State } from './../store';
|
||||
|
||||
import http from '../http';
|
||||
|
||||
export default function Offer(offer) {
|
||||
const ws = useSelector((state: State) => state.ws);
|
||||
|
||||
const { want: { data: details } } = offer;
|
||||
|
||||
const [accepted, setAccepted] = useState(offer.status !== 'Pending');
|
||||
|
||||
async function onClick() {
|
||||
const [error] = await http.postOfferAccept(offer.id);
|
||||
if (error) return false;
|
||||
setAccepted(true);
|
||||
function setStatus(status) {
|
||||
ws.sendOfferStatusSet(offer.id, status);
|
||||
}
|
||||
|
||||
const accepted = offer.status === 'Accepted';
|
||||
const classes = `${accepted ? 'accepted' : ''}`;
|
||||
const btnText = accepted
|
||||
? offer.status
|
||||
: 'Accept';
|
||||
|
||||
const negBtn = accepted
|
||||
? 'Cancel'
|
||||
: 'decline';
|
||||
|
||||
return (
|
||||
<div class="offer">
|
||||
<section>
|
||||
@@ -30,7 +36,8 @@ export default function Offer(offer) {
|
||||
<h5 class='number'>shipped by itself: ${offer.comparison}</h5>
|
||||
</section>
|
||||
<img src={details.thumb} />
|
||||
<button onClick={onClick} disabled={accepted} class={classes} >{btnText}</button>
|
||||
<button onClick={() => setStatus('Accepted')} disabled={accepted} class={classes} >{btnText}</button>
|
||||
<button class='neg'>{negBtn}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -90,19 +90,6 @@ const actions = {
|
||||
baseShipping,
|
||||
});
|
||||
},
|
||||
|
||||
postOfferAccept: async function postOffers(id) {
|
||||
return api.post('/offer/accept', {
|
||||
id,
|
||||
});
|
||||
},
|
||||
|
||||
postOfferStatus: async function postOfferStatus(id, status) {
|
||||
return api.post('/acp/offer/status', {
|
||||
id,
|
||||
status,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default actions;
|
||||
@@ -2,7 +2,6 @@ import { h } from 'preact';
|
||||
import { useState, useEffect } from 'preact/hooks';
|
||||
|
||||
import http from './../http';
|
||||
import AcpOffer from './../components/acp.offer';
|
||||
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { State } from './../store';
|
||||
@@ -24,7 +23,7 @@ function Item({ item }) {
|
||||
));
|
||||
|
||||
function onChange(e) {
|
||||
ws.sendOfferStatusSet(item.id, e.target.value);
|
||||
ws.sendAcpOfferStatusSet(item.id, e.target.value);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -58,16 +57,12 @@ function SellerGroup(group) {
|
||||
}
|
||||
|
||||
function Home() {
|
||||
const [offers, setOffers] = useState([]);
|
||||
const offers = useSelector((state: State) => state.acpOffers);
|
||||
const ws = useSelector((state: State) => state.ws);
|
||||
|
||||
useEffect(() => {
|
||||
async function getOffers() {
|
||||
const [error, offers] = await http.getOffersAcp();
|
||||
if (error) return console.error(error);
|
||||
setOffers(offers);
|
||||
}
|
||||
getOffers();
|
||||
}, []);
|
||||
// useEffect(() => {
|
||||
// ws.sendAcpOffers();
|
||||
// }, [offers, ws]);
|
||||
|
||||
if (!offers.length) {
|
||||
return (
|
||||
@@ -77,7 +72,6 @@ function Home() {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<div class='bundles'>
|
||||
{offers.map(SellerGroup)}
|
||||
|
||||
@@ -17,6 +17,14 @@ export const offersState = createSlice({
|
||||
},
|
||||
});
|
||||
|
||||
export const acpOffersState = createSlice({
|
||||
name: 'acpOffers',
|
||||
initialState: [],
|
||||
reducers: {
|
||||
set: (state, action) => action.payload
|
||||
},
|
||||
});
|
||||
|
||||
export const wantsState = createSlice({
|
||||
name: 'wants',
|
||||
initialState: [],
|
||||
@@ -38,6 +46,8 @@ const reducer = combineReducers({
|
||||
wants: wantsState.reducer,
|
||||
ws: wsState.reducer,
|
||||
user: userState.reducer,
|
||||
|
||||
acpOffers: acpOffersState.reducer,
|
||||
});
|
||||
|
||||
const store = createStore(
|
||||
|
||||
@@ -329,7 +329,7 @@ header {
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"details img"
|
||||
"btn btn";
|
||||
"btn neg";
|
||||
|
||||
padding: var(--base-spacing);
|
||||
margin: var(--base-spacing-half);
|
||||
@@ -352,6 +352,11 @@ header {
|
||||
background: var(--color-accent-blue);
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
&.neg {
|
||||
margin-left: var(--base-spacing-half);
|
||||
grid-area: neg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-1
@@ -1,4 +1,4 @@
|
||||
import { wantsState, wsState, userState } from './store'
|
||||
import { wantsState, wsState, userState, offersState, acpOffersState } from './store'
|
||||
|
||||
const SOCKET_URL = `${window.location.protocol === 'https:' ? 'wss://' : 'ws://'}${window.location.host}/api/ws`;
|
||||
|
||||
@@ -34,6 +34,14 @@ export default function createSocket(dispatch) {
|
||||
send(['WantRm', { id }]);
|
||||
}
|
||||
|
||||
function sendAcpOffers() {
|
||||
send(['AcpOffers', {}]);
|
||||
}
|
||||
|
||||
function sendAcpOfferStatusSet(id, status) {
|
||||
send(['AcpOfferStatusSet', { id, status }]);
|
||||
}
|
||||
|
||||
let pongTimeout;
|
||||
function onPong() {
|
||||
pongTimeout = setTimeout(sendPing, 5000);
|
||||
@@ -50,6 +58,14 @@ export default function createSocket(dispatch) {
|
||||
dispatch(wantsState.actions.set(wants));
|
||||
}
|
||||
|
||||
function onOffers(offers) {
|
||||
dispatch(offersState.actions.set(offers));
|
||||
}
|
||||
|
||||
function onAcpOffers(offers) {
|
||||
dispatch(acpOffersState.actions.set(offers));
|
||||
}
|
||||
|
||||
// -------------
|
||||
// Setup
|
||||
// -------------
|
||||
@@ -57,8 +73,11 @@ export default function createSocket(dispatch) {
|
||||
// this object wraps the reply types to a function
|
||||
const handlers = {
|
||||
Wants: onWants,
|
||||
Offers: onOffers,
|
||||
User: onUser,
|
||||
|
||||
AcpOffers: onAcpOffers,
|
||||
|
||||
Pong: onPong,
|
||||
Error: errHandler,
|
||||
};
|
||||
@@ -84,6 +103,7 @@ export default function createSocket(dispatch) {
|
||||
function onOpen() {
|
||||
console.log('websocket connected', SOCKET_URL)
|
||||
sendPing();
|
||||
sendAcpOffers();
|
||||
}
|
||||
|
||||
function onError(event) {
|
||||
@@ -122,5 +142,8 @@ export default function createSocket(dispatch) {
|
||||
|
||||
sendOfferStatusSet,
|
||||
sendWantRm,
|
||||
|
||||
sendAcpOffers,
|
||||
sendAcpOfferStatusSet,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user