Files
ambersplace.net/cohost-archive/~cohost-dl/dist/artist-alley-DC1Fn39_.js

1045 lines
42 KiB
JavaScript

if (!window.define) {
const modules = {};
window.__modules = modules;
const modulePromises = {};
const thisScriptSource = document.currentScript.getAttribute('src');
const srcDir = thisScriptSource.substring(0, thisScriptSource.lastIndexOf('/'));
const load = (id) => {
if (modules[id]) return modules[id];
if (modulePromises[id]) return modulePromises[id];
return modulePromises[id] = new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = srcDir + '/' + id + '.js';
script.onload = () => modules[id].then(resolve);
script.onerror = err => reject(new Error('failed to load ' + id));
script.dataset.id = id;
document.head.append(script);
});
};
const require = (ids, callback) => {
Promise.all(ids.map(load)).then(items => {
if (items.length === 1) callback(items[0]);
else callback(items);
});
};
window.require = require;
require.context = (dir, useSubdirs) => {
if ((dir === "../../images/emoji" || dir === "../images/emoji") && !useSubdirs) {
const data = {"chunks.png":"f59b84127fa7b6c48b6c.png","eggbug-classic.png":"41454e429d62b5cb7963.png","eggbug.png":"17aa2d48956926005de9.png","sixty.png":"9a6014af31fb1ca65a1f.png","unyeah.png":"5cf84d596a2c422967de.png","yeah.png":"014b0a8cc35206ef151d.png"};
const f = (n) => data[n];
f.keys = () => Object.keys(data);
return f;
} else if ((dir === "../../images/plus-emoji" || dir === "../images/plus-emoji") && !useSubdirs) {
const data = {"eggbug-asleep.png":"ebbf360236a95b62bdfc.png","eggbug-devious.png":"c4f3f2c6b9ffb85934e7.png","eggbug-heart-sob.png":"b59709333449a01e3e0a.png","eggbug-nervous.png":"d2753b632211c395538e.png","eggbug-pensive.png":"ae53a8b5de7c919100e6.png","eggbug-pleading.png":"11c5493261064ffa82c0.png","eggbug-relieved.png":"3633c116f0941d94d237.png","eggbug-shocked.png":"b25a9fdf230219087003.png","eggbug-smile-hearts.png":"d7ec7f057e6fb15a94cc.png","eggbug-sob.png":"9559ff8058a895328d76.png","eggbug-tuesday.png":"90058099e741e483208a.png","eggbug-uwu.png":"228d3a13bd5f7796b434.png","eggbug-wink.png":"3bc3a1c5272e2ceb8712.png","host-aww.png":"9bb403f3822c6457baf6.png","host-cry.png":"530f8cf75eac87716702.png","host-evil.png":"cb9a5640d7ef7b361a1a.png","host-frown.png":"99c7fbf98de865cc9726.png","host-joy.png":"53635f5fe850274b1a7d.png","host-love.png":"c45b6d8f9de20f725b98.png","host-nervous.png":"e5d55348f39c65a20148.png","host-plead.png":"fa883e2377fea8945237.png","host-shock.png":"bfa6d6316fd95ae76803.png","host-stare.png":"a09d966cd188c9ebaa4c.png"};
const f = (n) => data[n];
f.keys = () => Object.keys(data);
return f;
}
throw new Error('not supported: require.context for ' + dir);
};
window.define = (imports, exec) => {
if (typeof imports === 'function') {
exec = imports;
imports = [];
}
const id = document.currentScript.dataset.id
?? './' + document.currentScript.getAttribute('src').split('/').pop().replace(/\.js$/i, '');
if (modules[id]) return;
const exports = {};
modules[id] = Promise.resolve().then(function() {
const imported = [];
for (const id of imports) {
if (id === 'require') imported.push(Promise.resolve(require));
else if (id === 'exports') imported.push(Promise.resolve(exports));
else imported.push(load(id));
}
return Promise.all(imported);
}).then(function(imported) {
const result = exec.apply(window, imported);
if (!('default' in exports)) exports.default = result;
return exports;
});
};
window.process = { env: { NODE_ENV: 'production' } };
}
define(['exports', './post-page', './artist-alley-listing-Dn2_eERZ'], (function (exports, postPage, artistAlleyListing) { 'use strict';
const useTransitionState = (...args) => {
const [state, setState] = postPage.reactExports.useState(...args);
const [isTransitioning, startTransition] = postPage.reactExports.useTransition();
const setStateWithTransition = (newState) => {
startTransition(() => {
setState(newState);
});
};
return [state, setStateWithTransition];
};
const ArtistAlleyApprovalStatus = postPage.mod.enum([
"approved",
"pending",
"rejected",
]);
const ArtistAlleyPaymentStatus = postPage.mod.enum(["paid", "unpaid", "refunded"]);
postPage.mod.object({
altText: postPage.mod.string(),
attachmentFilename: postPage.mod.string(),
ip: postPage.mod.string(),
});
const ArtistAlleyWireAttachment = postPage.mod.object({
altText: postPage.mod.string(),
previewURL: postPage.mod.string().url(),
fileURL: postPage.mod.string().url(),
});
postPage.mod.enum(["hide", "include", "only"]);
const WireArtistAlley = postPage.mod.object({
id: postPage.ArtistAlleyAdId,
projectId: postPage.ProjectId,
expiresAt: postPage.ISODateString,
createdAt: postPage.ISODateString,
body: postPage.mod.string(),
cta: postPage.mod.object({
link: postPage.mod.string().url(),
text: postPage.mod.string(),
}),
attachment: ArtistAlleyWireAttachment.nullable(),
categories: postPage.mod.array(postPage.mod.string()),
adultContent: postPage.mod.boolean(),
});
WireArtistAlley.extend({
userId: postPage.UserId,
status: ArtistAlleyApprovalStatus,
paymentStatus: ArtistAlleyPaymentStatus,
stripeCheckoutSessionId: postPage.mod.string().nullable(),
stripePaymentIntentId: postPage.mod.string().nullable(),
rejectReason: postPage.mod.string().nullable(),
numWeeks: postPage.mod.number().int(),
notes: postPage.mod.string().nullable(),
});
WireArtistAlley.extend({
userId: postPage.UserId,
status: ArtistAlleyApprovalStatus,
paymentStatus: ArtistAlleyPaymentStatus,
rejectReason: postPage.mod.string().nullable(),
numWeeks: postPage.mod.number().int(),
notes: postPage.mod.string().nullable(),
receiptUrl: postPage.mod.string().url().nullable(),
});
function useSet(values) {
const setRef = postPage.reactExports.useRef(new Set(values));
const [, reRender] = postPage.reactExports.useReducer((x) => x + 1, 0);
setRef.current.add = (...args) => {
const res = Set.prototype.add.apply(setRef.current, args);
reRender();
return res;
};
setRef.current.clear = (...args) => {
Set.prototype.clear.apply(setRef.current, args);
reRender();
};
setRef.current.delete = (...args) => {
const res = Set.prototype.delete.apply(setRef.current, args);
reRender();
return res;
};
return setRef.current;
}
// src/observe.ts
var observerMap = /* @__PURE__ */ new Map();
var RootIds = /* @__PURE__ */ new WeakMap();
var rootId = 0;
var unsupportedValue = void 0;
function getRootId(root) {
if (!root)
return "0";
if (RootIds.has(root))
return RootIds.get(root);
rootId += 1;
RootIds.set(root, rootId.toString());
return RootIds.get(root);
}
function optionsToId(options) {
return Object.keys(options).sort().filter(
(key) => options[key] !== void 0
).map((key) => {
return `${key}_${key === "root" ? getRootId(options.root) : options[key]}`;
}).toString();
}
function createObserver(options) {
const id = optionsToId(options);
let instance = observerMap.get(id);
if (!instance) {
const elements = /* @__PURE__ */ new Map();
let thresholds;
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
var _a;
const inView = entry.isIntersecting && thresholds.some((threshold) => entry.intersectionRatio >= threshold);
if (options.trackVisibility && typeof entry.isVisible === "undefined") {
entry.isVisible = inView;
}
(_a = elements.get(entry.target)) == null ? void 0 : _a.forEach((callback) => {
callback(inView, entry);
});
});
}, options);
thresholds = observer.thresholds || (Array.isArray(options.threshold) ? options.threshold : [options.threshold || 0]);
instance = {
id,
observer,
elements
};
observerMap.set(id, instance);
}
return instance;
}
function observe(element, callback, options = {}, fallbackInView = unsupportedValue) {
if (typeof window.IntersectionObserver === "undefined" && fallbackInView !== void 0) {
const bounds = element.getBoundingClientRect();
callback(fallbackInView, {
isIntersecting: fallbackInView,
target: element,
intersectionRatio: typeof options.threshold === "number" ? options.threshold : 0,
time: 0,
boundingClientRect: bounds,
intersectionRect: bounds,
rootBounds: bounds
});
return () => {
};
}
const { id, observer, elements } = createObserver(options);
const callbacks = elements.get(element) || [];
if (!elements.has(element)) {
elements.set(element, callbacks);
}
callbacks.push(callback);
observer.observe(element);
return function unobserve() {
callbacks.splice(callbacks.indexOf(callback), 1);
if (callbacks.length === 0) {
elements.delete(element);
observer.unobserve(element);
}
if (elements.size === 0) {
observer.disconnect();
observerMap.delete(id);
}
};
}
function useInView({
threshold,
delay,
trackVisibility,
rootMargin,
root,
triggerOnce,
skip,
initialInView,
fallbackInView,
onChange
} = {}) {
var _a;
const [ref, setRef] = postPage.reactExports.useState(null);
const callback = postPage.reactExports.useRef();
const [state, setState] = postPage.reactExports.useState({
inView: !!initialInView,
entry: void 0
});
callback.current = onChange;
postPage.reactExports.useEffect(
() => {
if (skip || !ref)
return;
let unobserve;
unobserve = observe(
ref,
(inView, entry) => {
setState({
inView,
entry
});
if (callback.current)
callback.current(inView, entry);
if (entry.isIntersecting && triggerOnce && unobserve) {
unobserve();
unobserve = void 0;
}
},
{
root,
rootMargin,
threshold,
// @ts-ignore
trackVisibility,
// @ts-ignore
delay
},
fallbackInView
);
return () => {
if (unobserve) {
unobserve();
}
};
},
// We break the rule here, because we aren't including the actual `threshold` variable
// eslint-disable-next-line react-hooks/exhaustive-deps
[
// If the threshold is an array, convert it to a string, so it won't change between renders.
Array.isArray(threshold) ? threshold.toString() : threshold,
ref,
root,
rootMargin,
triggerOnce,
skip,
trackVisibility,
fallbackInView,
delay
]
);
const entryTarget = (_a = state.entry) == null ? void 0 : _a.target;
const previousEntryTarget = postPage.reactExports.useRef();
if (!ref && entryTarget && !triggerOnce && !skip && previousEntryTarget.current !== entryTarget) {
previousEntryTarget.current = entryTarget;
setState({
inView: !!initialInView,
entry: void 0
});
}
const result = [setRef, state.inView, state.entry];
result.ref = result[0];
result.inView = result[1];
result.entry = result[2];
return result;
}
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const defaultProps = {
breakpointCols: undefined,
// optional, number or object { default: number, [key: number]: number }
className: undefined,
// required, string
columnClassName: undefined,
// optional, string
// Any React children. Typically an array of JSX items
children: undefined,
// Custom attributes, however it is advised against
// using these to prevent unintended issues and future conflicts
// ...any other attribute, will be added to the container
columnAttrs: undefined,
// object, added to the columns
// Deprecated props
// The column property is deprecated.
// It is an alias of the `columnAttrs` property
column: undefined
};
const DEFAULT_COLUMNS = 2;
class Masonry extends postPage.React.Component {
constructor(props) {
super(props); // Correct scope for when methods are accessed externally
this.reCalculateColumnCount = this.reCalculateColumnCount.bind(this);
this.reCalculateColumnCountDebounce = this.reCalculateColumnCountDebounce.bind(this); // default state
let columnCount;
if (this.props.breakpointCols && this.props.breakpointCols.default) {
columnCount = this.props.breakpointCols.default;
} else {
columnCount = parseInt(this.props.breakpointCols) || DEFAULT_COLUMNS;
}
this.state = {
columnCount
};
}
componentDidMount() {
this.reCalculateColumnCount(); // window may not be available in some environments
if (window) {
window.addEventListener('resize', this.reCalculateColumnCountDebounce);
}
}
componentDidUpdate() {
this.reCalculateColumnCount();
}
componentWillUnmount() {
if (window) {
window.removeEventListener('resize', this.reCalculateColumnCountDebounce);
}
}
reCalculateColumnCountDebounce() {
if (!window || !window.requestAnimationFrame) {
// IE10+
this.reCalculateColumnCount();
return;
}
if (window.cancelAnimationFrame) {
// IE10+
window.cancelAnimationFrame(this._lastRecalculateAnimationFrame);
}
this._lastRecalculateAnimationFrame = window.requestAnimationFrame(() => {
this.reCalculateColumnCount();
});
}
reCalculateColumnCount() {
const windowWidth = window && window.innerWidth || Infinity;
let breakpointColsObject = this.props.breakpointCols; // Allow passing a single number to `breakpointCols` instead of an object
if (typeof breakpointColsObject !== 'object') {
breakpointColsObject = {
default: parseInt(breakpointColsObject) || DEFAULT_COLUMNS
};
}
let matchedBreakpoint = Infinity;
let columns = breakpointColsObject.default || DEFAULT_COLUMNS;
for (let breakpoint in breakpointColsObject) {
const optBreakpoint = parseInt(breakpoint);
const isCurrentBreakpoint = optBreakpoint > 0 && windowWidth <= optBreakpoint;
if (isCurrentBreakpoint && optBreakpoint < matchedBreakpoint) {
matchedBreakpoint = optBreakpoint;
columns = breakpointColsObject[breakpoint];
}
}
columns = Math.max(1, parseInt(columns) || 1);
if (this.state.columnCount !== columns) {
this.setState({
columnCount: columns
});
}
}
itemsInColumns() {
const currentColumnCount = this.state.columnCount;
const itemsInColumns = new Array(currentColumnCount); // Force children to be handled as an array
const items = postPage.React.Children.toArray(this.props.children);
for (let i = 0; i < items.length; i++) {
const columnIndex = i % currentColumnCount;
if (!itemsInColumns[columnIndex]) {
itemsInColumns[columnIndex] = [];
}
itemsInColumns[columnIndex].push(items[i]);
}
return itemsInColumns;
}
renderColumns() {
const {
column,
columnAttrs = {},
columnClassName
} = this.props;
const childrenInColumns = this.itemsInColumns();
const columnWidth = `${100 / childrenInColumns.length}%`;
let className = columnClassName;
if (className && typeof className !== 'string') {
this.logDeprecated('The property "columnClassName" requires a string'); // This is a deprecated default and will be removed soon.
if (typeof className === 'undefined') {
className = 'my-masonry-grid_column';
}
}
const columnAttributes = _objectSpread(_objectSpread(_objectSpread({}, column), columnAttrs), {}, {
style: _objectSpread(_objectSpread({}, columnAttrs.style), {}, {
width: columnWidth
}),
className
});
return childrenInColumns.map((items, i) => {
return /*#__PURE__*/postPage.React.createElement("div", _extends({}, columnAttributes, {
key: i
}), items);
});
}
logDeprecated(message) {
console.error('[Masonry]', message);
}
render() {
const _this$props = this.props,
{
// ignored
children,
breakpointCols,
columnClassName,
columnAttrs,
column,
// used
className
} = _this$props,
rest = _objectWithoutProperties(_this$props, ["children", "breakpointCols", "columnClassName", "columnAttrs", "column", "className"]);
let classNameOutput = className;
if (typeof className !== 'string') {
this.logDeprecated('The property "className" requires a string'); // This is a deprecated default and will be removed soon.
if (typeof className === 'undefined') {
classNameOutput = 'my-masonry-grid';
}
}
return /*#__PURE__*/postPage.React.createElement("div", _extends({}, rest, {
className: classNameOutput
}), this.renderColumns());
}
}
Masonry.defaultProps = defaultProps;
const MultiSwitchButton
= ({ tabs }) => {
return (
postPage.React.createElement('ul', { className: "co-multi-button mx-auto my-2 flex w-auto max-w-fit flex-row items-center justify-evenly overflow-y-auto whitespace-nowrap rounded-lg" ,}
, tabs.map((tab) => (
postPage.React.createElement('li', {
key: `${tab.label}`,
className: `co-multi-button px-3 py-2 text-center text-sm first-of-type:rounded-l-lg last-of-type:rounded-r-lg ${
tab.active
? "co-active rounded-lg rounded-b-lg font-bold first-of-type:rounded-bl-none last-of-type:rounded-br-none"
: ""
}`,}
, postPage.React.createElement('button', { onClick: tab.onClick,}, tab.label)
)
))
)
);
};
const ArtistAlleyFilters
= ({ className }) => {
const postBoxTheme = postPage.useDynamicTheme();
const isDesktop = postPage.useMedia("(min-width: 1200px)", true);
const [allCategories] =
postPage.trpc.artistAlley.getCategoriesInUse.useSuspenseQuery(undefined, {
refetchInterval: Infinity,
keepPreviousData: true,
});
const { loggedIn } = postPage.useUserInfo();
const { data: hasPurchasedListing } =
postPage.trpc.artistAlley.hasPurchasedListing.useQuery(undefined, {
enabled: loggedIn,
suspense: true,
});
const {
adultFilterMode,
setAdultFilterMode,
categories,
isAdult,
categoryMatch,
setCategoryMatch,
sortOrder,
setSortOrder,
} = artistAlleyListing.useArtistAlleyFilters();
return (
postPage.React.createElement(postPage.React.Fragment, null
, postPage.React.createElement(postPage.ve, {
as: "div",
'data-theme': postBoxTheme.current,
className: postPage.tw`co-themed-box co-artist-alley-filters cohost-shadow-light dark:cohost-shadow-dark col-span-1 flex h-fit max-h-max min-h-0 w-full flex-col rounded-lg border ${
className ?? ""
}`,
defaultOpen: isDesktop,}
, postPage.React.createElement(postPage.ve.Button, {
as: "header",
className: "flex flex-row items-center justify-between rounded-t-lg p-3 ui-not-open:rounded-b-lg" ,}
, postPage.React.createElement(postPage.ForwardRef$2, { className: "h-5 w-5 ui-open:rotate-90 motion-safe:transition-transform" ,} )
, postPage.React.createElement('span', { className: "font-league text-xs uppercase" ,}, "filters"
)
)
, postPage.React.createElement(postPage.ve.Panel, { as: "div",}
, postPage.React.createElement('div', { className: "flex flex-row flex-wrap gap-2 px-3 py-2" ,}
, allCategories.map((category) => (
postPage.React.createElement('div', {
key: `selected-token-${category}`,
className: "group h-max cursor-pointer select-none" ,}
/* this weird nested div thing is to prevent a bug caused by having the default click handler and our removal handler on the same element */
, postPage.React.createElement('button', {
className: postPage.tw`co-token flex items-center justify-start gap-1 rounded-lg px-2 py-1 leading-none ${
categories.has(category)
? "co-active"
: ""
}`,
onClick: (e) => {
e.stopPropagation();
categories.has(category)
? categories.delete(category)
: categories.add(category);
},
type: "button",}
, postPage.React.createElement(postPage.ForwardRef$3, { className: "inline-block h-3.5" ,} )
, postPage.React.createElement('span', { className: "block",}, category)
)
)
))
)
, postPage.React.createElement(MultiSwitchButton, {
tabs: [
{
label: "any",
onClick: () => setCategoryMatch("any"),
active: categoryMatch === "any",
},
{
label: "all",
onClick: () => setCategoryMatch("all"),
active: categoryMatch === "all",
},
],}
)
, isAdult && (
postPage.React.createElement(postPage.React.Fragment, null
, postPage.React.createElement('hr', { className: "border-notWhite",} )
, postPage.React.createElement(MultiSwitchButton, {
tabs: [
{
label: "hide 18+",
onClick: () => {
setAdultFilterMode("hide");
},
active: adultFilterMode === "hide",
},
{
label: "show 18+",
onClick: () => {
setAdultFilterMode("include");
},
active: adultFilterMode === "include",
},
{
label: "only 18+",
onClick: () => {
setAdultFilterMode("only");
},
active: adultFilterMode === "only",
},
],}
)
)
)
, postPage.React.createElement('hr', { className: "border-notWhite",} )
, postPage.React.createElement(MultiSwitchButton, {
tabs: [
{
label: "random",
onClick: () => {
setSortOrder("random");
},
active: sortOrder === "random",
},
{
label: "newest first",
onClick: () => {
setSortOrder("newest");
},
active: sortOrder === "newest",
},
{
label: "oldest first",
onClick: () => {
setSortOrder("oldest");
},
active: sortOrder === "oldest",
},
],}
)
)
)
, postPage.React.createElement(postPage.ve, {
as: "div",
'data-theme': postBoxTheme.current,
className: postPage.tw`co-themed-box co-artist-alley-filters cohost-shadow-light dark:cohost-shadow-dark col-span-1 mt-4 flex h-fit max-h-max min-h-0 w-full flex-col rounded-lg border ${
className ?? ""
}`,
defaultOpen: isDesktop,}
, postPage.React.createElement(postPage.ve.Button, {
as: "header",
className: "flex flex-row items-center justify-between rounded-t-lg p-3 ui-not-open:rounded-b-lg" ,}
, postPage.React.createElement(postPage.ForwardRef$2, { className: "h-5 w-5 ui-open:rotate-90 motion-safe:transition-transform" ,} )
, postPage.React.createElement('span', { className: "font-league text-xs uppercase" ,}, "your listing here!"
)
)
, postPage.React.createElement(postPage.ve.Panel, { as: "div", className: "p-3",}
, postPage.React.createElement('div', { className: "co-prose prose mb-3" ,}
, postPage.React.createElement('p', null, "are you an artist, musician, game developer, or other creative? got something you want cohost users to know about? get an artist alley listing! only $10 per week!"
)
)
, postPage.React.createElement(postPage.BasicButton, {
buttonSize: "regular",
buttonColor: "post-box-filled",
as: "a",
href: postPage.sitemap.public.artistAlley.create().toString(),
extraClasses: "mt-2",}
, "buy a listing"
)
, hasPurchasedListing && (
postPage.React.createElement(postPage.BasicButton, {
buttonSize: "regular",
buttonColor: "post-box-filled",
as: "a",
href: postPage.sitemap.public.artistAlley
.ownerManage()
.toString(),
extraClasses: "mt-2",}
, "manage your listings"
)
)
)
)
)
);
};
function generateMasonryBreakpoints(
maxCols
) {
const breakpoints = {
default: 1,
};
// breakpoints are based on a max-width, so we need to set the breakpoint
// based on the maximum number of columns below that width. columns are max
// 300px, so 2 columns requires a min-width of 600px, meaning 1 column has a
// max-width of 600px. i swear this makes sense. - jkap, 4/23/24
for (let i = 1; i <= maxCols; i++) {
breakpoints[300 * (i + 1)] = i;
}
// since it's based on max-width, we set a fallback breakpoint that's
// impossible to hit so that we don't snap back to 1 column on larger
// screens.
breakpoints[Number.MAX_SAFE_INTEGER] = maxCols + 1;
return breakpoints;
}
const ArtistAlleyPage = () => {
const { isAdult, explicitlyCollapseAdultContent } = postPage.useDisplayPrefs();
const [adultState, setAdultFilterMode] =
useTransitionState(
// if the user is an adult, use their display setting. otherwise,
// default to hiding adult content
isAdult
? explicitlyCollapseAdultContent
? "hide"
: "include"
: "hide"
);
const [categoryMatch, setCategoryMatch] =
useTransitionState("any");
const categories = useSet();
const artistAlleyLive = postPage.index_browserExports.useFlag(postPage.FeatureFlag.Enum["artist-alley-listings"]);
const [sortOrder, setSortOrder] = useTransitionState("random");
return (
postPage.React.createElement(artistAlleyListing.ArtistAlleyFilterProvider.Provider, {
value: {
adultFilterMode: adultState,
isAdult,
categories,
setAdultFilterMode,
categoryMatch,
setCategoryMatch,
sortOrder,
setSortOrder,
},}
, postPage.React.createElement('div', { className: "styled-scrollbars-light dark:styled-scrollbars-dark styled-scrollbars-light dark:styled-scrollbars-dark container mx-auto flex w-full max-w-full flex-row [height:calc(100vh-4rem)]" ,}
, postPage.React.createElement(postPage.Helmet, { title: "artist alley" ,} )
, postPage.React.createElement(postPage.SidebarMenu, { narrowMode: true,} )
, artistAlleyLive ? (
postPage.React.createElement(postPage.reactExports.Suspense, { fallback: postPage.React.createElement('div', null, "aaaaaaa"),}
, postPage.React.createElement(ArtistAlleyInner, null )
)
) : (
postPage.React.createElement(ArtistAlleyClosed, null )
)
)
)
);
};
const ArtistAlleyClosed = () => {
const theme = postPage.useDynamicTheme();
return (
postPage.React.createElement('div', { className: "mt-12",}
, postPage.React.createElement('div', { 'data-theme': theme.current, className: "co-themed-box co-static" ,}
, postPage.React.createElement('div', { className: "co-prose prose" ,}
, postPage.React.createElement('h1', null, "artist alley is currently closed" )
, postPage.React.createElement('p', null, "we're still working on getting everything set up! if you're interested in buying a listing, you can do so on the"
, " "
, postPage.React.createElement('a', {
href: postPage.sitemap.public.artistAlley
.create()
.toString(),}
, "sign up page!"
)
)
, postPage.React.createElement('p', null, "artist alley should be live soon. check out"
, " "
, postPage.React.createElement('a', { href: "https://cohost.org/staff",}, "@staff"), " for the most recent info!"
)
)
)
)
);
};
// doing this with zod because i was having trouble getting typescript to handle
// the discriminated union correctly otherwise
postPage.mod.discriminatedUnion("type", [
postPage.mod.object({
type: postPage.mod.literal("LISTING"),
id: postPage.ArtistAlleyAdId,
listing: WireArtistAlley,
project: postPage.WireProjectModel,
}),
postPage.mod.object({ type: postPage.mod.literal("FILTER"), id: postPage.mod.literal("FILTER") }),
]);
const ArtistAlleyInner = () => {
const toastId = postPage.reactExports.useRef(undefined);
const { operatingPrime } = postPage.useSiteConfig();
const { adultFilterMode, categories, categoryMatch, sortOrder } =
artistAlleyListing.useArtistAlleyFilters();
const [{ pages }, { fetchNextPage, fetchStatus }] =
postPage.trpc.artistAlley.getListingsForDisplay.useSuspenseInfiniteQuery(
{
adultDisplayMode: adultFilterMode,
categories: Array.from(categories),
sortModulus: operatingPrime,
categoryMatch,
sortOrder,
},
{
getNextPageParam: (lastPage) => lastPage.nextCursor,
keepPreviousData: true,
// never refetch, each page load should be fully deterministic
refetchInterval: Infinity,
refetchOnMount: false,
refetchOnReconnect: false,
refetchOnWindowFocus: false,
refetchIntervalInBackground: false,
// toast management
onError: (err) => {
postPage.n.error(err.message, {
id: toastId.current,
});
},
onSuccess: () => {
postPage.n.dismiss(toastId.current);
},
}
);
postPage.reactExports.useEffect(() => {
if (fetchStatus === "fetching") {
toastId.current = postPage.n.loading("loading listings...", {
id: toastId.current,
});
}
}, [fetchStatus]);
const flattenedListings = postPage.reactExports.useMemo(() => {
return pages.flatMap((page) => page.listings) ?? [];
}, [pages]);
const flattenedProjects = postPage.reactExports.useMemo(() => {
const projects = new Map();
pages.forEach((page) => {
Object.values(page.relevantProjects).forEach((project) => {
projects.set(project.projectId, project);
});
});
return projects;
}, [pages]);
const masonicListings = postPage.reactExports.useMemo(() => {
const val = flattenedListings
.map((listing) => {
const project = flattenedProjects.get(listing.projectId);
if (!project) return undefined;
return {
type: "LISTING",
id: listing.id,
listing,
project,
};
})
.filter(postPage.isDefined);
// inject the filter sentinel item at the beginning so it's rendered in the right place
val.unshift({ type: "FILTER", id: "FILTER" });
return val;
}, [flattenedListings, flattenedProjects]);
const { ref, inView } = useInView();
postPage.reactExports.useEffect(() => {
if (inView) {
postPage.reactExports.startTransition(() => {
void fetchNextPage();
});
}
}, [inView, fetchNextPage]);
const masonryBreakpoints = postPage.reactExports.useMemo(() => {
return generateMasonryBreakpoints(20);
}, []);
return (
postPage.React.createElement('div', { className: "flex w-full flex-col gap-4" ,}
, postPage.React.createElement(Masonry, {
breakpointCols: masonryBreakpoints,
className: "artist-alley-grid w-full" ,
columnClassName: "artist-alley-grid_column",}
, masonicListings.map((listing) => (
postPage.React.createElement(ListingMasonryWrapper, { key: listing.id, data: listing,} )
))
)
/* marker so we can load the next page */
, postPage.React.createElement('div', { className: "h-[1px] w-[1px] flex-shrink-0" , ref: ref,})
)
);
};
const ListingMasonryWrapper
= ({ data }) => {
if (data.type === "LISTING")
return (
postPage.React.createElement('div', {
key: data.listing.id,
className: "mt-4 inline-block w-full max-w-[300px]" ,}
, postPage.React.createElement(artistAlleyListing.ArtistAlleyListing, {
listing: data.listing,
project: data.project,}
)
)
);
return (
postPage.React.createElement('div', { key: data.id, className: "mt-4 inline-block w-full max-w-[300px]" ,}
, postPage.React.createElement(ArtistAlleyFilters, null )
)
);
};
exports.ArtistAlleyPage = ArtistAlleyPage;
exports.default = ArtistAlleyPage;
}));