|
|
|
//
|
|
|
|
// IndexView.swift
|
|
|
|
// Weibo
|
|
|
|
//
|
|
|
|
// Created by Qihua Pan on 2020/8/18.
|
|
|
|
// Copyright © 2020 Qihua Pan. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
import SwiftUI
|
|
|
|
import AlamofireImage
|
|
|
|
import CoreData
|
|
|
|
import SwiftyJSON
|
|
|
|
import Alamofire
|
|
|
|
struct ButtonView:View{
|
|
|
|
var title:String
|
|
|
|
var action:() -> Void
|
|
|
|
|
|
|
|
@Binding var activeMenu:String
|
|
|
|
|
|
|
|
func isActive(name:String)->Color{
|
|
|
|
if name==self.activeMenu{
|
|
|
|
return Color.orange
|
|
|
|
}else{
|
|
|
|
return Color.black
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var body: some View{
|
|
|
|
Button(action: action) {
|
|
|
|
Text(title)
|
|
|
|
.foregroundColor(isActive(name: title))
|
|
|
|
}
|
|
|
|
.padding(.all, 10.0)
|
|
|
|
.frame(width: 90.0)
|
|
|
|
.background(Color(red: 222/255, green: 223/255, blue: 222/255, opacity: 1.0))
|
|
|
|
.clipShape(Rectangle())
|
|
|
|
.cornerRadius(3)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TextView:View {
|
|
|
|
var title:String
|
|
|
|
var isActive:Bool
|
|
|
|
var body: some View{
|
|
|
|
if isActive{
|
|
|
|
return Text(title)
|
|
|
|
.foregroundColor(Color.black)
|
|
|
|
.fontWeight(/*@START_MENU_TOKEN@*/.bold/*@END_MENU_TOKEN@*/)
|
|
|
|
}else{
|
|
|
|
return Text(title)
|
|
|
|
.foregroundColor(Color.gray)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct TopView:View {
|
|
|
|
|
|
|
|
@Binding var icon: String
|
|
|
|
|
|
|
|
@State var activeMenu:String="最新微博"
|
|
|
|
|
|
|
|
@State var menuIndex=0
|
|
|
|
|
|
|
|
@Binding var isSend:Bool
|
|
|
|
|
|
|
|
var body: some View{
|
|
|
|
VStack {
|
|
|
|
HStack {
|
|
|
|
Image("user-search-line")
|
|
|
|
Spacer()
|
|
|
|
HStack{
|
|
|
|
Button(action: {
|
|
|
|
if self.icon=="arrowbottom"{
|
|
|
|
self.icon="arrowtop"
|
|
|
|
}else{
|
|
|
|
self.icon="arrowbottom"
|
|
|
|
}
|
|
|
|
self.menuIndex=0
|
|
|
|
}) {
|
|
|
|
HStack {
|
|
|
|
TextView(title: self.activeMenu, isActive: self.menuIndex==0)
|
|
|
|
Image(self.icon)
|
|
|
|
.padding(.leading, -9.0)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Button(action: {
|
|
|
|
print("推荐")
|
|
|
|
self.menuIndex=1
|
|
|
|
}){
|
|
|
|
TextView(title: "推荐", isActive: self.menuIndex==1)
|
|
|
|
}
|
|
|
|
Button(action: {
|
|
|
|
print("同城")
|
|
|
|
self.menuIndex=2
|
|
|
|
}){
|
|
|
|
TextView(title: "同城", isActive: self.menuIndex==2)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Spacer()
|
|
|
|
HStack(){
|
|
|
|
Image("red packet")
|
|
|
|
Image("edit").onTapGesture(perform: {
|
|
|
|
self.isSend=true
|
|
|
|
})
|
|
|
|
}
|
|
|
|
.padding(.trailing, 18.0)
|
|
|
|
.frame(width: nil)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if self.icon=="arrowbottom"{
|
|
|
|
HStack {
|
|
|
|
Text("默认分组")
|
|
|
|
.foregroundColor(Color.gray)
|
|
|
|
Spacer()
|
|
|
|
Button(action: {
|
|
|
|
print("编辑分组")
|
|
|
|
}){
|
|
|
|
Text("编辑")
|
|
|
|
.foregroundColor(Color.orange)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
.padding(EdgeInsets(top: 5, leading: 20, bottom: 0, trailing: 20))
|
|
|
|
HStack(spacing: 10.0){
|
|
|
|
ButtonView(title: "全部关注", action: {
|
|
|
|
print("全部关注")
|
|
|
|
self.activeMenu="全部关注"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "最新微博", action: {
|
|
|
|
print("最新微博")
|
|
|
|
self.activeMenu="最新微博"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "特别关注", action: {
|
|
|
|
print("特别关注")
|
|
|
|
self.activeMenu="特别关注"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "好友圈", action: {
|
|
|
|
print("好友圈")
|
|
|
|
self.activeMenu="好友圈"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
}
|
|
|
|
.padding(.top, 10.0)
|
|
|
|
HStack(spacing: 10.0){
|
|
|
|
ButtonView(title: "原创", action: {
|
|
|
|
print("原创")
|
|
|
|
self.activeMenu="原创"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "视频", action: {
|
|
|
|
print("视频")
|
|
|
|
self.activeMenu="视频"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "V+微博", action: {
|
|
|
|
print("V+微博")
|
|
|
|
self.activeMenu="V+微博"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "群微博", action: {
|
|
|
|
print("群微博")
|
|
|
|
self.activeMenu="群微博"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
}
|
|
|
|
.padding(.top, 10.0)
|
|
|
|
HStack {
|
|
|
|
Text("我的分组")
|
|
|
|
.foregroundColor(Color.gray)
|
|
|
|
.padding(.leading, 20.0)
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
.padding(.top, 10.0)
|
|
|
|
HStack(spacing: 10.0){
|
|
|
|
ButtonView(title: "名人明星", action: {
|
|
|
|
print("名人明星")
|
|
|
|
self.activeMenu="名人明星"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "同事", action: {
|
|
|
|
print("同事")
|
|
|
|
self.activeMenu="同事"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "同学", action: {
|
|
|
|
print("同学")
|
|
|
|
self.activeMenu="同学"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
ButtonView(title: "悄悄关注", action: {
|
|
|
|
print("悄悄关注")
|
|
|
|
self.activeMenu="悄悄关注"
|
|
|
|
self.icon="arrowtop"
|
|
|
|
},activeMenu: self.$activeMenu)
|
|
|
|
}
|
|
|
|
.padding(.top, 10.0)
|
|
|
|
HStack(){
|
|
|
|
|
|
|
|
Button(action: /*@START_MENU_TOKEN@*/{}/*@END_MENU_TOKEN@*/) {
|
|
|
|
Text("+新建分组")
|
|
|
|
}
|
|
|
|
.foregroundColor(Color.black)
|
|
|
|
.padding(10.0)
|
|
|
|
.frame(width: 100.0)
|
|
|
|
.overlay(Rectangle()
|
|
|
|
.stroke(Color.gray, style: StrokeStyle(lineWidth: 2, dash: [5])))
|
|
|
|
Spacer()
|
|
|
|
|
|
|
|
}
|
|
|
|
.padding(10.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ImageView:View {
|
|
|
|
var imageUrl:String
|
|
|
|
var body: some View{
|
|
|
|
Image(uiImage: requestImage(url: imageUrl))
|
|
|
|
}
|
|
|
|
|
|
|
|
func requestImage(url:String)->UIImage{
|
|
|
|
|
|
|
|
let data = try! Data(contentsOf: URL(string: url)!)
|
|
|
|
let image = UIImage(data: data, scale: UIScreen.main.scale)!
|
|
|
|
image.af.inflate()
|
|
|
|
return image
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct RowView:View {
|
|
|
|
|
|
|
|
var content:Content
|
|
|
|
|
|
|
|
var body: some View{
|
|
|
|
VStack {
|
|
|
|
HStack{
|
|
|
|
ImageView(imageUrl:self.content.user.headUrl)
|
|
|
|
.frame(width: 60.0, height: 60.0)
|
|
|
|
.clipShape(/*@START_MENU_TOKEN@*/Circle()/*@END_MENU_TOKEN@*/)
|
|
|
|
VStack(alignment: .leading){
|
|
|
|
Text(self.content.user.name)
|
|
|
|
Text("\(self.content.created_at) 来自 weibo....")
|
|
|
|
.foregroundColor(Color.gray)
|
|
|
|
.padding(.top, 5.0)
|
|
|
|
}
|
|
|
|
.padding(.leading, 10.0)
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
.padding(.leading, 20.0)
|
|
|
|
Text(self.content.content)
|
|
|
|
.fontWeight(.bold)
|
|
|
|
.padding([.top, .leading, .trailing], 5.0)
|
|
|
|
.lineSpacing(/*@START_MENU_TOKEN@*/4.0/*@END_MENU_TOKEN@*/).lineLimit(5)
|
|
|
|
Text("")
|
|
|
|
|
|
|
|
HStack {
|
|
|
|
ForEach(self.content.picUrl, id: \.self){
|
|
|
|
url in
|
|
|
|
ImageView(imageUrl: url).onTapGesture(perform: {
|
|
|
|
print("url=\(url)")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Rectangle()
|
|
|
|
.frame(height: 1)
|
|
|
|
HStack {
|
|
|
|
Image("share")
|
|
|
|
Text(String(self.content.share))
|
|
|
|
.scaleEffect(/*@START_MENU_TOKEN@*/1.5/*@END_MENU_TOKEN@*/)
|
|
|
|
Spacer()
|
|
|
|
Image("comment")
|
|
|
|
Text(String(self.content.comment))
|
|
|
|
.scaleEffect(/*@START_MENU_TOKEN@*/1.5/*@END_MENU_TOKEN@*/)
|
|
|
|
Spacer()
|
|
|
|
Image("like")
|
|
|
|
Text(String(self.content.like))
|
|
|
|
.scaleEffect(/*@START_MENU_TOKEN@*/1.5/*@END_MENU_TOKEN@*/)
|
|
|
|
}
|
|
|
|
.padding(.horizontal, 10.0)
|
|
|
|
Rectangle()
|
|
|
|
.frame(height: 20.0)
|
|
|
|
.foregroundColor(Color(red: 219/255, green: 220/255, blue: 219/255, opacity: 1.0))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct LoadView:View {
|
|
|
|
@State var angle:Double=0
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
VStack {
|
|
|
|
Image("loading")
|
|
|
|
.rotationEffect(.degrees(self.angle))
|
|
|
|
.animation(
|
|
|
|
Animation.linear(duration:3)
|
|
|
|
.repeatForever(autoreverses: false)).onAppear(perform: {
|
|
|
|
self.angle=360
|
|
|
|
})
|
|
|
|
Text("正在加载中")
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct UserInfo{
|
|
|
|
var id:Int
|
|
|
|
var headUrl:String
|
|
|
|
var name:String
|
|
|
|
}
|
|
|
|
|
|
|
|
struct Content:Identifiable {
|
|
|
|
|
|
|
|
var id:Int
|
|
|
|
var user:UserInfo
|
|
|
|
var content:String
|
|
|
|
var share:Int
|
|
|
|
var comment:Int
|
|
|
|
var like:Int
|
|
|
|
var picUrl:[String]
|
|
|
|
var source:String
|
|
|
|
var created_at:String
|
|
|
|
}
|
|
|
|
|
|
|
|
struct IndexView: View {
|
|
|
|
|
|
|
|
@State var icon: String="arrowtop"
|
|
|
|
|
|
|
|
@Environment(\.managedObjectContext) var contenxt:NSManagedObjectContext
|
|
|
|
|
|
|
|
@EnvironmentObject var user:User
|
|
|
|
|
|
|
|
@State var statuses:[Content]=[]
|
|
|
|
|
|
|
|
let queue=OperationQueue()
|
|
|
|
|
|
|
|
@State var angle:Double=0
|
|
|
|
|
|
|
|
@State var isSend=false
|
|
|
|
|
|
|
|
@State var showTip=true
|
|
|
|
|
|
|
|
func tansformDate(dateStr:String)->String{
|
|
|
|
let formatter = DateFormatter()
|
|
|
|
|
|
|
|
formatter.dateFormat = "EEEE MMM dd HH:mm:ss zzz yyyy"
|
|
|
|
let datestr = formatter.date(from: dateStr)
|
|
|
|
let unix=datestr?.timeIntervalSince1970
|
|
|
|
|
|
|
|
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
|
|
|
|
let date = Date(timeIntervalSince1970: unix!)
|
|
|
|
return formatter.string(from: date)
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func loadContent(){
|
|
|
|
self.showTip=true
|
|
|
|
if let access_token=self.user.access_token{
|
|
|
|
print("加载用户\(String(describing: self.user.uid))关注用户的最新微博")
|
|
|
|
AF.request("https://api.weibo.com/2/statuses/friends_timeline.json",parameters: ["access_token":access_token]).responseJSON { response in
|
|
|
|
self.showTip=false
|
|
|
|
if let data=response.data,let json = try? JSON(data: data){
|
|
|
|
if let statuses = json["statuses"].array {
|
|
|
|
self.statuses.removeAll()
|
|
|
|
for statuse in statuses{
|
|
|
|
if let id = statuse["user"]["id"].int,
|
|
|
|
let headUrl=statuse["user"]["avatar_hd"].string,
|
|
|
|
let name=statuse["user"]["name"].string,
|
|
|
|
let statuse_id=statuse["id"].int,
|
|
|
|
let content=statuse["text"].string,
|
|
|
|
let source=statuse["source"].string,
|
|
|
|
let share=statuse["reposts_count"].int,
|
|
|
|
let comment=statuse["comments_count"].int,
|
|
|
|
let like=statuse["attitudes_count"].int,
|
|
|
|
let pic_urls=statuse["pic_urls"].array,
|
|
|
|
let created_at=statuse["created_at"].string
|
|
|
|
{
|
|
|
|
let obj=Content(id: statuse_id, user: UserInfo(id: id, headUrl: headUrl, name: name), content: content, share: share, comment: comment, like: like, picUrl: pic_urls.map({ json in
|
|
|
|
json["thumbnail_pic"].stringValue
|
|
|
|
}),source: source,created_at: self.tansformDate(dateStr: created_at))
|
|
|
|
self.statuses.append(obj)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
print("解析\(self.statuses.count)条微博数据")
|
|
|
|
}else{
|
|
|
|
print("loadUserInfo error:\(response.error)")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var body: some View {
|
|
|
|
|
|
|
|
|
|
|
|
VStack {
|
|
|
|
if self.isSend{
|
|
|
|
SendView(flag: {
|
|
|
|
self.isSend=false
|
|
|
|
})
|
|
|
|
}else{
|
|
|
|
TopView(icon: $icon, isSend: self.$isSend).onAppear(perform: {
|
|
|
|
self.loadContent()
|
|
|
|
})
|
|
|
|
if self.showTip{
|
|
|
|
Spacer()
|
|
|
|
LoadView()
|
|
|
|
Spacer()
|
|
|
|
|
|
|
|
}
|
|
|
|
List(self.statuses){
|
|
|
|
data in
|
|
|
|
RowView(content: data)
|
|
|
|
}.onAppear(perform: {
|
|
|
|
self.showTip=false
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct IndexView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
|
|
|
IndexView()
|
|
|
|
}
|
|
|
|
}
|