Profile: supports webfinger
* timelines: add emptyTimeline
This commit is contained in:
		
							parent
							
								
									f860baa376
								
							
						
					
					
						commit
						7153a1fec1
					
				
					 2 changed files with 96 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -248,6 +248,64 @@ export type TimelineResource<R> = [
 | 
			
		|||
  { refetch(info?: TimelineFetchDirection): void },
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
export const emptyTimeline = {
 | 
			
		||||
  list() {
 | 
			
		||||
    return emptyTimeline;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  setDirection() {
 | 
			
		||||
    return emptyTimeline;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async next(): Promise<IteratorResult<any, undefined>> {
 | 
			
		||||
    return {
 | 
			
		||||
      value: undefined,
 | 
			
		||||
      done: true,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  getDirection(): TimelineFetchDirection {
 | 
			
		||||
    return "next";
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  clone() {
 | 
			
		||||
    return emptyTimeline;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async return(): Promise<IteratorResult<any, undefined>> {
 | 
			
		||||
    return {
 | 
			
		||||
      value: undefined,
 | 
			
		||||
      done: true,
 | 
			
		||||
    };
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async throw(e?: unknown) {
 | 
			
		||||
    throw e;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async *values() {},
 | 
			
		||||
  async *[Symbol.asyncIterator](): AsyncIterator<any[], undefined> {
 | 
			
		||||
    return undefined;
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async then<TNext, ENext>(
 | 
			
		||||
    onresolve?: null | ((value: any[]) => TNext | PromiseLike<TNext>),
 | 
			
		||||
    onrejected?: null | ((reason: unknown) => ENext | PromiseLike<ENext>),
 | 
			
		||||
  ) {
 | 
			
		||||
    try {
 | 
			
		||||
      if (!onresolve) {
 | 
			
		||||
        throw new TypeError("no onresolve");
 | 
			
		||||
      }
 | 
			
		||||
      return await onresolve([]);
 | 
			
		||||
    } catch (reason) {
 | 
			
		||||
      if (!onrejected) {
 | 
			
		||||
        throw reason;
 | 
			
		||||
      }
 | 
			
		||||
      return await onrejected(reason);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Create auto managed timeline controls.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,11 @@ import { useSessionForAcctStr } from "../masto/clients";
 | 
			
		|||
import { resolveCustomEmoji } from "../masto/toot";
 | 
			
		||||
import { FastAverageColor } from "fast-average-color";
 | 
			
		||||
import { useWindowSize } from "@solid-primitives/resize-observer";
 | 
			
		||||
import { createTimeline, createTimelineSnapshot } from "../masto/timelines";
 | 
			
		||||
import {
 | 
			
		||||
  createTimeline,
 | 
			
		||||
  createTimelineSnapshot,
 | 
			
		||||
  emptyTimeline,
 | 
			
		||||
} from "../masto/timelines";
 | 
			
		||||
import TootList from "../timelines/TootList";
 | 
			
		||||
import { createTimeSource, TimeSourceProvider } from "~platform/timesrc";
 | 
			
		||||
import TootFilterButton from "./TootFilterButton";
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +106,9 @@ const Profile: Component = () => {
 | 
			
		|||
  const [profileUncaught] = createResource(
 | 
			
		||||
    () => [session().client, params.id] as const,
 | 
			
		||||
    async ([client, id]) => {
 | 
			
		||||
      if (id.startsWith("@")) {
 | 
			
		||||
        return await client.v1.accounts.lookup({ acct: id.slice(1) });
 | 
			
		||||
      }
 | 
			
		||||
      return await client.v1.accounts.$select(id).fetch();
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			@ -114,6 +121,15 @@ const Profile: Component = () => {
 | 
			
		|||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const profileAcctId = () => {
 | 
			
		||||
    if (params.id.startsWith("@")) {
 | 
			
		||||
      // Webfinger
 | 
			
		||||
      return profile()?.id;
 | 
			
		||||
    } else {
 | 
			
		||||
      return params.id;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const isCurrentSessionProfile = () => {
 | 
			
		||||
    return (session().account as Account).inf?.url === profile()?.url;
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -125,26 +141,33 @@ const Profile: Component = () => {
 | 
			
		|||
    original: true,
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const recentTimeline = () => {
 | 
			
		||||
    const id = profileAcctId();
 | 
			
		||||
 | 
			
		||||
    if (id) {
 | 
			
		||||
      return session().client.v1.accounts.$select(id).statuses;
 | 
			
		||||
    } else {
 | 
			
		||||
      return emptyTimeline;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const [recentToots, recentTootChunk, { refetch: refetchRecentToots }] =
 | 
			
		||||
    createTimeline(
 | 
			
		||||
      () => session().client.v1.accounts.$select(params.id).statuses,
 | 
			
		||||
      () => {
 | 
			
		||||
        const { boost, reply } = recentTootFilter();
 | 
			
		||||
        return { limit: 20, excludeReblogs: !boost, excludeReplies: !reply };
 | 
			
		||||
      },
 | 
			
		||||
    );
 | 
			
		||||
    createTimeline(recentTimeline, () => {
 | 
			
		||||
      const { boost, reply } = recentTootFilter();
 | 
			
		||||
      return { limit: 20, excludeReblogs: !boost, excludeReplies: !reply };
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  const [pinnedToots, pinnedTootChunk] = createTimelineSnapshot(
 | 
			
		||||
    () => session().client.v1.accounts.$select(params.id).statuses,
 | 
			
		||||
    recentTimeline,
 | 
			
		||||
    () => {
 | 
			
		||||
      return { limit: 20, pinned: true };
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  const [relationshipUncaught, { mutate: mutateRelationship }] = createResource(
 | 
			
		||||
    () => [session(), params.id] as const,
 | 
			
		||||
    () => [session(), profileAcctId()] as const,
 | 
			
		||||
    async ([sess, id]) => {
 | 
			
		||||
      if (!sess.account) return; // No account, no relation
 | 
			
		||||
      if (!sess.account || !id) return; // No account, no relation
 | 
			
		||||
      const relations = await session().client.v1.accounts.relationships.fetch({
 | 
			
		||||
        id: [id],
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			@ -177,16 +200,17 @@ const Profile: Component = () => {
 | 
			
		|||
 | 
			
		||||
  const toggleSubscribeHome = async (event: Event) => {
 | 
			
		||||
    const client = session().client;
 | 
			
		||||
    if (!session().account) return;
 | 
			
		||||
    const acctId = profileAcctId();
 | 
			
		||||
    if (!session().account || !acctId) return;
 | 
			
		||||
    const isSubscribed = relationship()?.following ?? false;
 | 
			
		||||
    mutateRelationship((x) => Object.assign({ following: !isSubscribed }, x));
 | 
			
		||||
    subscribeMenuState.onClose(event);
 | 
			
		||||
 | 
			
		||||
    if (isSubscribed) {
 | 
			
		||||
      const nrel = await client.v1.accounts.$select(params.id).unfollow();
 | 
			
		||||
      const nrel = await client.v1.accounts.$select(acctId).unfollow();
 | 
			
		||||
      mutateRelationship(nrel);
 | 
			
		||||
    } else {
 | 
			
		||||
      const nrel = await client.v1.accounts.$select(params.id).follow();
 | 
			
		||||
      const nrel = await client.v1.accounts.$select(acctId).follow();
 | 
			
		||||
      mutateRelationship(nrel);
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue